source: trunk/poppler/freetype-2.1.10/src/truetype/ttpload.c @ 2

Last change on this file since 2 was 2, checked in by Eugene Romanenko, 16 years ago

First import

File size: 14.4 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  ttpload.c                                                              */
4/*                                                                         */
5/*    TrueType glyph data/program tables loader (body).                    */
6/*                                                                         */
7/*  Copyright 1996-2001, 2002, 2004, 2005 by                               */
8/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9/*                                                                         */
10/*  This file is part of the FreeType project, and may only be used,       */
11/*  modified, and distributed under the terms of the FreeType project      */
12/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13/*  this file you indicate that you have read the license and              */
14/*  understand and accept it fully.                                        */
15/*                                                                         */
16/***************************************************************************/
17
18
19#include <ft2build.h>
20#include FT_INTERNAL_DEBUG_H
21#include FT_INTERNAL_OBJECTS_H
22#include FT_INTERNAL_STREAM_H
23#include FT_TRUETYPE_TAGS_H
24
25#include "ttpload.h"
26
27#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
28#include "ttgxvar.h"
29#endif
30
31#include "tterrors.h"
32
33
34  /*************************************************************************/
35  /*                                                                       */
36  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
37  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
38  /* messages during execution.                                            */
39  /*                                                                       */
40#undef  FT_COMPONENT
41#define FT_COMPONENT  trace_ttpload
42
43
44  /*************************************************************************/
45  /*                                                                       */
46  /* <Function>                                                            */
47  /*    tt_face_load_loca                                                  */
48  /*                                                                       */
49  /* <Description>                                                         */
50  /*    Loads the locations table.                                         */
51  /*                                                                       */
52  /* <InOut>                                                               */
53  /*    face   :: A handle to the target face object.                      */
54  /*                                                                       */
55  /* <Input>                                                               */
56  /*    stream :: The input stream.                                        */
57  /*                                                                       */
58  /* <Return>                                                              */
59  /*    FreeType error code.  0 means success.                             */
60  /*                                                                       */
61#ifdef FT_OPTIMIZE_MEMORY
62
63  FT_LOCAL_DEF( FT_Error )
64  tt_face_load_loca( TT_Face    face,
65                     FT_Stream  stream )
66  {
67    FT_Error  error;
68    FT_ULong  table_len;
69
70
71    /* we need the size of the `glyf' table for malformed `loca' tables */
72    error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len );
73    if ( error )
74      goto Exit;
75
76    FT_TRACE2(( "Locations " ));
77    error = face->goto_table( face, TTAG_loca, stream, &table_len );
78    if ( error )
79    {
80      error = TT_Err_Locations_Missing;
81      goto Exit;
82    }
83
84    if ( face->header.Index_To_Loc_Format != 0 )
85    {
86      if ( table_len >= 0x40000 )
87      {
88        FT_TRACE2(( "table too large!\n" ));
89        error = TT_Err_Invalid_Table;
90        goto Exit;
91      }
92      face->num_locations = (FT_UInt)( table_len >> 2 );
93    }
94    else
95    {
96      if ( table_len >= 0x20000 )
97      {
98        FT_TRACE2(( "table too large!\n" ));
99        error = TT_Err_Invalid_Table;
100        goto Exit;
101      }
102      face->num_locations = (FT_UInt)( table_len >> 1 );
103    }
104
105    /*
106     * Extract the frame.  We don't need to decompress it since
107     * we are able to parse it directly.
108     */
109    if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) )
110      goto Exit;
111
112    FT_TRACE2(( "loaded\n" ));
113
114  Exit:
115    return error;
116  }
117
118
119  FT_LOCAL_DEF( FT_ULong )
120  tt_face_get_location( TT_Face   face,
121                        FT_UInt   gindex,
122                        FT_UInt  *asize )
123  {
124    FT_ULong  pos1, pos2;
125    FT_Byte*  p;
126    FT_Byte*  p_limit;
127
128
129    pos1 = pos2 = 0;
130
131    if ( gindex < face->num_locations )
132    {
133      if ( face->header.Index_To_Loc_Format != 0 )
134      {
135        p       = face->glyph_locations + gindex * 4;
136        p_limit = face->glyph_locations + face->num_locations * 4;
137
138        pos1 = FT_NEXT_ULONG( p );
139        pos2 = pos1;
140
141        if ( p + 4 <= p_limit )
142          pos2 = FT_NEXT_ULONG( p );
143      }
144      else
145      {
146        p       = face->glyph_locations + gindex * 2;
147        p_limit = face->glyph_locations + face->num_locations * 2;
148
149        pos1 = FT_NEXT_USHORT( p );
150        pos2 = pos1;
151
152        if ( p + 2 <= p_limit )
153          pos2 = FT_NEXT_USHORT( p );
154
155        pos1 <<= 1;
156        pos2 <<= 1;
157      }
158    }
159
160    /* It isn't mentioned explicitly that the `loca' table must be  */
161    /* ordered, but implicitly it refers to the length of an entry  */
162    /* as the difference between the current and the next position. */
163    /* Anyway, there do exist (malformed) fonts which don't obey    */
164    /* this rule, so we are only able to provide an upper bound for */
165    /* the size.                                                    */
166    if ( pos2 >= pos1 )
167      *asize = (FT_UInt)( pos2 - pos1 );
168    else
169      *asize = (FT_UInt)( face->glyf_len - pos1 );
170
171    return pos1;
172  }
173
174
175  FT_LOCAL_DEF( void )
176  tt_face_done_loca( TT_Face  face )
177  {
178    FT_Stream  stream = face->root.stream;
179
180
181    FT_FRAME_RELEASE( face->glyph_locations );
182    face->num_locations = 0;
183  }
184
185
186#else /* !FT_OPTIMIZE_MEMORY */
187
188
189  FT_LOCAL_DEF( FT_Error )
190  tt_face_load_loca( TT_Face    face,
191                     FT_Stream  stream )
192  {
193    FT_Error   error;
194    FT_Memory  memory = stream->memory;
195    FT_Short   LongOffsets;
196    FT_ULong   table_len;
197
198
199    /* we need the size of the `glyf' table for malformed `loca' tables */
200    error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len );
201    if ( error )
202      goto Exit;
203
204    FT_TRACE2(( "Locations " ));
205    LongOffsets = face->header.Index_To_Loc_Format;
206
207    error = face->goto_table( face, TTAG_loca, stream, &table_len );
208    if ( error )
209    {
210      error = TT_Err_Locations_Missing;
211      goto Exit;
212    }
213
214    if ( LongOffsets != 0 )
215    {
216      face->num_locations = (FT_UShort)( table_len >> 2 );
217
218      FT_TRACE2(( "(32bit offsets): %12d ", face->num_locations ));
219
220      if ( FT_NEW_ARRAY( face->glyph_locations, face->num_locations ) )
221        goto Exit;
222
223      if ( FT_FRAME_ENTER( face->num_locations * 4L ) )
224        goto Exit;
225
226      {
227        FT_Long*  loc   = face->glyph_locations;
228        FT_Long*  limit = loc + face->num_locations;
229
230
231        for ( ; loc < limit; loc++ )
232          *loc = FT_GET_LONG();
233      }
234
235      FT_FRAME_EXIT();
236    }
237    else
238    {
239      face->num_locations = (FT_UShort)( table_len >> 1 );
240
241      FT_TRACE2(( "(16bit offsets): %12d ", face->num_locations ));
242
243      if ( FT_NEW_ARRAY( face->glyph_locations, face->num_locations ) )
244        goto Exit;
245
246      if ( FT_FRAME_ENTER( face->num_locations * 2L ) )
247        goto Exit;
248
249      {
250        FT_Long*  loc   = face->glyph_locations;
251        FT_Long*  limit = loc + face->num_locations;
252
253
254        for ( ; loc < limit; loc++ )
255          *loc = (FT_Long)( (FT_ULong)FT_GET_USHORT() * 2 );
256      }
257
258      FT_FRAME_EXIT();
259    }
260
261    FT_TRACE2(( "loaded\n" ));
262
263  Exit:
264    return error;
265  }
266
267
268  FT_LOCAL_DEF( FT_ULong )
269  tt_face_get_location( TT_Face   face,
270                        FT_UInt   gindex,
271                        FT_UInt  *asize )
272  {
273    FT_ULong  offset;
274    FT_UInt   count;
275
276
277    offset = face->glyph_locations[gindex];
278    count  = 0;
279
280    if ( gindex < (FT_UInt)face->num_locations - 1 )
281    {
282      FT_ULong  offset1 = face->glyph_locations[gindex + 1];
283
284
285      /* It isn't mentioned explicitly that the `loca' table must be  */
286      /* ordered, but implicitly it refers to the length of an entry  */
287      /* as the difference between the current and the next position. */
288      /* Anyway, there do exist (malformed) fonts which don't obey    */
289      /* this rule, so we are only able to provide an upper bound for */
290      /* the size.                                                    */
291      if ( offset1 >= offset )
292        count = (FT_UInt)( offset1 - offset );
293      else
294        count = (FT_UInt)( face->glyf_len - offset );
295    }
296
297    *asize = count;
298    return offset;
299  }
300
301
302  FT_LOCAL_DEF( void )
303  tt_face_done_loca( TT_Face  face )
304  {
305    FT_Memory  memory = face->root.memory;
306
307
308    FT_FREE( face->glyph_locations );
309    face->num_locations = 0;
310  }
311
312
313#endif /* !FT_OPTIMIZE_MEMORY */
314
315
316  /*************************************************************************/
317  /*                                                                       */
318  /* <Function>                                                            */
319  /*    tt_face_load_cvt                                                   */
320  /*                                                                       */
321  /* <Description>                                                         */
322  /*    Loads the control value table into a face object.                  */
323  /*                                                                       */
324  /* <InOut>                                                               */
325  /*    face   :: A handle to the target face object.                      */
326  /*                                                                       */
327  /* <Input>                                                               */
328  /*    stream :: A handle to the input stream.                            */
329  /*                                                                       */
330  /* <Return>                                                              */
331  /*    FreeType error code.  0 means success.                             */
332  /*                                                                       */
333  FT_LOCAL_DEF( FT_Error )
334  tt_face_load_cvt( TT_Face    face,
335                    FT_Stream  stream )
336  {
337#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
338
339    FT_Error   error;
340    FT_Memory  memory = stream->memory;
341    FT_ULong   table_len;
342
343
344    FT_TRACE2(( "CVT " ));
345
346    error = face->goto_table( face, TTAG_cvt, stream, &table_len );
347    if ( error )
348    {
349      FT_TRACE2(( "is missing!\n" ));
350
351      face->cvt_size = 0;
352      face->cvt      = NULL;
353      error          = TT_Err_Ok;
354
355      goto Exit;
356    }
357
358    face->cvt_size = table_len / 2;
359
360    if ( FT_NEW_ARRAY( face->cvt, face->cvt_size ) )
361      goto Exit;
362
363    if ( FT_FRAME_ENTER( face->cvt_size * 2L ) )
364      goto Exit;
365
366    {
367      FT_Short*  cur   = face->cvt;
368      FT_Short*  limit = cur + face->cvt_size;
369
370
371      for ( ; cur <  limit; cur++ )
372        *cur = FT_GET_SHORT();
373    }
374
375    FT_FRAME_EXIT();
376    FT_TRACE2(( "loaded\n" ));
377
378#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
379    if ( face->doblend )
380      error = tt_face_vary_cvt( face, stream );
381#endif
382
383  Exit:
384    return error;
385
386#else /* !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
387
388    FT_UNUSED( face   );
389    FT_UNUSED( stream );
390
391    return TT_Err_Ok;
392
393#endif
394  }
395
396
397  /*************************************************************************/
398  /*                                                                       */
399  /* <Function>                                                            */
400  /*    tt_face_load_fpgm                                                  */
401  /*                                                                       */
402  /* <Description>                                                         */
403  /*    Loads the font program and the cvt program.                        */
404  /*                                                                       */
405  /* <InOut>                                                               */
406  /*    face   :: A handle to the target face object.                      */
407  /*                                                                       */
408  /* <Input>                                                               */
409  /*    stream :: A handle to the input stream.                            */
410  /*                                                                       */
411  /* <Return>                                                              */
412  /*    FreeType error code.  0 means success.                             */
413  /*                                                                       */
414  FT_LOCAL_DEF( FT_Error )
415  tt_face_load_fpgm( TT_Face    face,
416                     FT_Stream  stream )
417  {
418#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
419
420    FT_Error   error;
421    FT_ULong   table_len;
422
423
424    FT_TRACE2(( "Font program " ));
425
426    /* The font program is optional */
427    error = face->goto_table( face, TTAG_fpgm, stream, &table_len );
428    if ( error )
429    {
430      face->font_program      = NULL;
431      face->font_program_size = 0;
432
433      FT_TRACE2(( "is missing!\n" ));
434    }
435    else
436    {
437      face->font_program_size = table_len;
438      if ( FT_FRAME_EXTRACT( table_len, face->font_program ) )
439        goto Exit;
440
441      FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size ));
442    }
443
444    FT_TRACE2(( "Prep program " ));
445
446    error = face->goto_table( face, TTAG_prep, stream, &table_len );
447    if ( error )
448    {
449      face->cvt_program      = NULL;
450      face->cvt_program_size = 0;
451      error                  = TT_Err_Ok;
452
453      FT_TRACE2(( "is missing!\n" ));
454    }
455    else
456    {
457      face->cvt_program_size = table_len;
458      if ( FT_FRAME_EXTRACT( table_len, face->cvt_program ) )
459        goto Exit;
460
461      FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size ));
462    }
463
464  Exit:
465    return error;
466
467#else /* !TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
468
469    FT_UNUSED( face   );
470    FT_UNUSED( stream );
471
472    return TT_Err_Ok;
473
474#endif
475  }
476
477
478/* END */
Note: See TracBrowser for help on using the repository browser.