1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  ttload.c                                                               */
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*    Load the basic TrueType tables, i.e., tables that can be either in   */
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*    TTF or OTF fonts (body).                                             */
7049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
8aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
9aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich/*            2010 by                                                      */
10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  This file is part of the FreeType project, and may only be used,       */
13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  modified, and distributed under the terms of the FreeType project      */
14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  this file you indicate that you have read the license and              */
16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  understand and accept it fully.                                        */
17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_STREAM_H
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_TRUETYPE_TAGS_H
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ttload.h"
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "sferrors.h"
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* messages during execution.                                            */
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_ttload
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_lookup_table                                               */
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Looks for a TrueType table by name.                                */
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face :: A face object handle.                                      */
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tag  :: The searched tag.                                          */
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    A pointer to the table directory entry.  0 if not found.           */
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( TT_Table  )
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_lookup_table( TT_Face   face,
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_ULong  tag  )
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_Table  entry;
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_Table  limit;
620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifdef FT_DEBUG_LEVEL_TRACE
630a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_Bool   zero_length = FALSE;
640a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE4(( "tt_face_lookup_table: %08p, `%c%c%c%c' -- ",
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                face,
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                (FT_Char)( tag >> 24 ),
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                (FT_Char)( tag >> 16 ),
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                (FT_Char)( tag >> 8  ),
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                (FT_Char)( tag       ) ));
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    entry = face->dir_tables;
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    limit = entry + face->num_tables;
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; entry < limit; entry++ )
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
790a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      /* For compatibility with Windows, we consider    */
800a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      /* zero-length tables the same as missing tables. */
81aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( entry->Tag == tag )
82aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      {
830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        if ( entry->Length != 0 )
840a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        {
850a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          FT_TRACE4(( "found table.\n" ));
860a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          return entry;
870a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        }
880a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifdef FT_DEBUG_LEVEL_TRACE
890a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        zero_length = TRUE;
900a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
940a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifdef FT_DEBUG_LEVEL_TRACE
950a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( zero_length )
96295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_TRACE4(( "ignoring empty table\n" ));
970a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    else
98295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_TRACE4(( "could not find table\n" ));
990a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif
1000a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1010a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    return NULL;
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_goto_table                                                 */
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Looks for a TrueType table by name, then seek a stream to it.      */
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face   :: A face object handle.                                    */
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tag    :: The searched tag.                                        */
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream :: The stream to seek when the table is found.              */
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Output>                                                              */
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    length :: The length of the table if found, undefined otherwise.   */
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_goto_table( TT_Face    face,
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ULong   tag,
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Stream  stream,
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ULong*  length )
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_Table  table;
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table = tt_face_lookup_table( face, tag );
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( table )
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( length )
140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *length = table->Length;
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_STREAM_SEEK( table->Offset ) )
1430a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        goto Exit;
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = SFNT_Err_Table_Missing;
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1530a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* Here, we                                                         */
1540a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*                                                                  */
1550a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* - check that `num_tables' is valid (and adjust it if necessary)  */
1560a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*                                                                  */
1570a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* - look for a `head' table, check its size, and parse it to check */
1580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*   whether its `magic' field is correctly set                     */
1590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*                                                                  */
1600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* - errors (except errors returned by stream handling)             */
1610a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*                                                                  */
1620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*     SFNT_Err_Unknown_File_Format:                                */
1630a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*       no table is defined in directory, it is not sfnt-wrapped   */
1640a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*       data                                                       */
1650a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*     SFNT_Err_Table_Missing:                                      */
1660a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*       table directory is valid, but essential tables             */
1670a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*       (head/bhed/SING) are missing                               */
1680a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*                                                                  */
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  check_table_dir( SFNT_Header  sfnt,
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Stream    stream )
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
173295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_Error   error;
174295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_UShort  nn, valid_entries = 0;
175295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_UInt    has_head = 0, has_sing = 0, has_meta = 0;
176295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_ULong   offset = sfnt->offset + 12;
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static const FT_Frame_Field  table_dir_entry_fields[] =
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_STRUCTURE
181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_STRUCTURE  TT_TableRec
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_START( 16 ),
184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG( Tag ),
185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG( CheckSum ),
186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG( Offset ),
187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG( Length ),
188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_END
189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_SEEK( offset ) )
1930a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      goto Exit;
194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( nn = 0; nn < sfnt->num_tables; nn++ )
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TT_TableRec  table;
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) )
2010a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      {
2020a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        nn--;
2030a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        FT_TRACE2(( "check_table_dir:"
2040a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                    " can read only %d table%s in font (instead of %d)\n",
2050a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                    nn, nn == 1 ? "" : "s", sfnt->num_tables ));
2060a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        sfnt->num_tables = nn;
2070a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        break;
2080a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      }
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2100a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      /* we ignore invalid tables */
2110a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( table.Offset + table.Length > stream->size )
2120a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      {
2130a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
2140a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        continue;
2150a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      }
2160a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      else
2170a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        valid_entries++;
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( table.Tag == TTAG_head || table.Tag == TTAG_bhed )
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_UInt32  magic;
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( table.Tag == TTAG_head )
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          has_head = 1;
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /*
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         * The table length should be 0x36, but certain font tools make it
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         * 0x38, so we will just check that it is greater.
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         *
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         * Note that according to the specification, the table must be
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         * padded to 32-bit lengths, but this doesn't apply to the value of
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         * its `Length' field!
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         *
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         */
238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( table.Length < 0x36 )
2390a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        {
2400a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          FT_TRACE2(( "check_table_dir: `head' table too small\n" ));
2410a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          error = SFNT_Err_Table_Missing;
2420a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          goto Exit;
2430a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        }
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_STREAM_SEEK( table.Offset + 12 ) ||
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_READ_ULONG( magic )              )
2470a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          goto Exit;
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( magic != 0x5F0F3CF5UL )
2500a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        {
2510a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          FT_TRACE2(( "check_table_dir:"
2520a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                      " no magic number found in `head' table\n"));
2530a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          error = SFNT_Err_Table_Missing;
2540a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          goto Exit;
2550a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        }
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_STREAM_SEEK( offset + ( nn + 1 ) * 16 ) )
2580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          goto Exit;
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( table.Tag == TTAG_SING )
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        has_sing = 1;
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( table.Tag == TTAG_META )
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        has_meta = 1;
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2660a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    sfnt->num_tables = valid_entries;
2670a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
2680a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( sfnt->num_tables == 0 )
2690a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    {
2700a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_TRACE2(( "check_table_dir: no tables found\n" ));
2710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      error = SFNT_Err_Unknown_File_Format;
2720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      goto Exit;
2730a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
2740a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if `sing' and `meta' tables are present, there is no `head' table */
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( has_head || ( has_sing && has_meta ) )
2770a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    {
2780a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      error = SFNT_Err_Ok;
2790a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      goto Exit;
2800a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
2820a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    {
2830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_TRACE2(( "check_table_dir:" ));
2840a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
2850a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_TRACE2(( " neither `head', `bhed', nor `sing' table found\n" ));
2860a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#else
2870a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_TRACE2(( " neither `head' nor `sing' table found\n" ));
2880a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif
2890a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      error = SFNT_Err_Table_Missing;
2900a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
2910a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
2920a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  Exit:
2930a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    return error;
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_load_font_dir                                              */
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Loads the header of a SFNT font file.                              */
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face       :: A handle to the target face object.                  */
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream     :: The input stream.                                    */
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Output>                                                              */
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    sfnt       :: The SFNT header.                                     */
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Note>                                                                */
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    The stream cursor must be at the beginning of the font directory.  */
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_font_dir( TT_Face    face,
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Stream  stream )
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    SFNT_HeaderRec  sfnt;
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error        error;
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory       memory = stream->memory;
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_TableRec*    entry;
3270a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_Int          nn;
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static const FT_Frame_Field  offset_table_fields[] =
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_STRUCTURE
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_STRUCTURE  SFNT_HeaderRec
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_START( 8 ),
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( num_tables ),
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( search_range ),
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( entry_selector ),
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( range_shift ),
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_END
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE2(( "tt_face_load_font_dir: %08p\n", face ));
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* read the offset table */
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    sfnt.offset = FT_STREAM_POS();
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_READ_ULONG( sfnt.format_tag )                    ||
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_STREAM_READ_FIELDS( offset_table_fields, &sfnt ) )
3510a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      goto Exit;
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* many fonts don't have these fields set correctly */
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 0
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( sfnt.search_range != 1 << ( sfnt.entry_selector + 4 )        ||
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         sfnt.search_range + sfnt.range_shift != sfnt.num_tables << 4 )
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return SFNT_Err_Unknown_File_Format;
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* load the table directory */
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_TRACE2(( "-- Number of tables: %10u\n",    sfnt.num_tables ));
3630a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_TRACE2(( "-- Format version:   0x%08lx\n", sfnt.format_tag ));
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check first */
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = check_table_dir( &sfnt, stream );
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
369295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_TRACE2(( "tt_face_load_font_dir:"
370295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                  " invalid table directory for TrueType\n" ));
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      goto Exit;
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->num_tables = sfnt.num_tables;
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->format_tag = sfnt.format_tag;
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) )
3790a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      goto Exit;
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_SEEK( sfnt.offset + 12 )       ||
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_FRAME_ENTER( face->num_tables * 16L ) )
3830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      goto Exit;
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    entry = face->dir_tables;
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3878583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner    FT_TRACE2(( "\n"
3888583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner                "  tag    offset    length   checksum\n"
3898583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner                "  ----------------------------------\n" ));
3908583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner
3910a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    for ( nn = 0; nn < sfnt.num_tables; nn++ )
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      entry->Tag      = FT_GET_TAG4();
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      entry->CheckSum = FT_GET_ULONG();
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      entry->Offset   = FT_GET_LONG();
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      entry->Length   = FT_GET_LONG();
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3980a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      /* ignore invalid tables */
3990a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( entry->Offset + entry->Length > stream->size )
4000a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        continue;
4010a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      else
4020a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      {
4038583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner        FT_TRACE2(( "  %c%c%c%c  %08lx  %08lx  %08lx\n",
4040a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                    (FT_Char)( entry->Tag >> 24 ),
4050a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                    (FT_Char)( entry->Tag >> 16 ),
4060a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                    (FT_Char)( entry->Tag >> 8  ),
4070a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                    (FT_Char)( entry->Tag       ),
4080a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                    entry->Offset,
4098583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner                    entry->Length,
4108583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner                    entry->CheckSum ));
4110a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        entry++;
4120a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      }
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FRAME_EXIT();
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE2(( "table directory loaded\n\n" ));
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4190a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  Exit:
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_load_any                                                   */
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Loads any font table into client memory.                           */
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face   :: The face object to look for.                             */
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tag    :: The tag of table to load.  Use the value 0 if you want   */
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*              to access the whole font file, else set this parameter   */
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*              to a valid TrueType table tag that you can forge with    */
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*              the MAKE_TT_TAG macro.                                   */
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    offset :: The starting offset in the table (or the file if         */
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*              tag == 0).                                               */
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    length :: The address of the decision variable:                    */
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                If length == NULL:                                     */
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                  Loads the whole table.  Returns an error if          */
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                  `offset' == 0!                                       */
448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                If *length == 0:                                       */
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                  Exits immediately; returning the length of the given */
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                  table or of the font file, depending on the value of */
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                  `tag'.                                               */
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                If *length != 0:                                       */
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                  Loads the next `length' bytes of table or font,      */
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                  starting at offset `offset' (in table or font too).  */
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Output>                                                              */
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    buffer :: The address of target buffer.                            */
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_any( TT_Face    face,
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_ULong   tag,
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Long    offset,
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Byte*   buffer,
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_ULong*  length )
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream  stream;
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_Table   table;
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong   size;
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( tag != 0 )
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* look for tag in font directory */
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      table = tt_face_lookup_table( face, tag );
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !table )
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = SFNT_Err_Table_Missing;
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      offset += table->Offset;
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      size    = table->Length;
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* tag == 0 -- the user wants to access the font file directly */
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      size = face->root.stream->size;
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( length && *length == 0 )
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *length = size;
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return SFNT_Err_Ok;
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( length )
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      size = *length;
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream = face->root.stream;
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the `if' is syntactic sugar for picky compilers */
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_READ_AT( offset, buffer, size ) )
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_load_generic_header                                        */
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Loads the TrueType table `head' or `bhed'.                         */
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face   :: A handle to the target face object.                      */
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream :: The input stream.                                        */
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_generic_header( TT_Face    face,
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_Stream  stream,
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_ULong   tag )
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error    error;
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_Header*  header;
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static const FT_Frame_Field  header_fields[] =
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_STRUCTURE
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_STRUCTURE  TT_Header
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_START( 54 ),
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG ( Table_Version ),
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG ( Font_Revision ),
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_LONG  ( CheckSum_Adjust ),
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_LONG  ( Magic_Number ),
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( Flags ),
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( Units_Per_EM ),
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_LONG  ( Created[0] ),
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_LONG  ( Created[1] ),
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_LONG  ( Modified[0] ),
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_LONG  ( Modified[1] ),
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( xMin ),
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( yMin ),
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( xMax ),
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( yMax ),
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( Mac_Style ),
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( Lowest_Rec_PPEM ),
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( Font_Direction ),
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( Index_To_Loc_Format ),
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( Glyph_Data_Format ),
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_END
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = face->goto_table( face, tag, stream, 0 );
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    header = &face->header;
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_READ_FIELDS( header_fields, header ) )
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE3(( "Units per EM: %4u\n", header->Units_Per_EM ));
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE3(( "IndexToLoc:   %4d\n", header->Index_To_Loc_Format ));
578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_head( TT_Face    face,
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream  stream )
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return tt_face_load_generic_header( face, stream, TTAG_head );
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_bhed( TT_Face    face,
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream  stream )
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return tt_face_load_generic_header( face, stream, TTAG_bhed );
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_load_max_profile                                           */
608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Loads the maximum profile into a face object.                      */
611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face   :: A handle to the target face object.                      */
614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream :: The input stream.                                        */
616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_maxp( TT_Face    face,
622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream  stream )
623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error        error;
625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_MaxProfile*  maxProfile = &face->max_profile;
626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const FT_Frame_Field  maxp_fields[] =
628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_STRUCTURE
630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_STRUCTURE  TT_MaxProfile
631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_START( 6 ),
633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_LONG  ( version ),
634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( numGlyphs ),
635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_END
636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const FT_Frame_Field  maxp_fields_extra[] =
639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_START( 26 ),
641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( maxPoints ),
642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( maxContours ),
643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( maxCompositePoints ),
644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( maxCompositeContours ),
645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( maxZones ),
646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( maxTwilightPoints ),
647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( maxStorage ),
648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( maxFunctionDefs ),
649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( maxInstructionDefs ),
650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( maxStackElements ),
651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( maxSizeOfInstructions ),
652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( maxComponentElements ),
653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( maxComponentDepth ),
654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_END
655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = face->goto_table( face, TTAG_maxp, stream, 0 );
659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_READ_FIELDS( maxp_fields, maxProfile ) )
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    maxProfile->maxPoints             = 0;
666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    maxProfile->maxContours           = 0;
667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    maxProfile->maxCompositePoints    = 0;
668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    maxProfile->maxCompositeContours  = 0;
669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    maxProfile->maxZones              = 0;
670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    maxProfile->maxTwilightPoints     = 0;
671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    maxProfile->maxStorage            = 0;
672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    maxProfile->maxFunctionDefs       = 0;
673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    maxProfile->maxInstructionDefs    = 0;
674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    maxProfile->maxStackElements      = 0;
675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    maxProfile->maxSizeOfInstructions = 0;
676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    maxProfile->maxComponentElements  = 0;
677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    maxProfile->maxComponentDepth     = 0;
678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( maxProfile->version >= 0x10000L )
680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_STREAM_READ_FIELDS( maxp_fields_extra, maxProfile ) )
682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* XXX: an adjustment that is necessary to load certain */
685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*      broken fonts like `Keystrokes MT' :-(           */
686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*                                                      */
687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*   We allocate 64 function entries by default when    */
6888583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner      /*   the maxFunctionDefs value is smaller.              */
689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
6908583905b8952672a083f21fd8945f329b98aa35bDavid 'Digit' Turner      if ( maxProfile->maxFunctionDefs < 64 )
691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        maxProfile->maxFunctionDefs = 64;
692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* we add 4 phantom points later */
694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) )
695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
696295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_TRACE0(( "tt_face_load_maxp:"
697295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                    " too much twilight points in `maxp' table;\n"
698295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                    "                  "
699295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                    " some glyphs might be rendered incorrectly\n" ));
700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        maxProfile->maxTwilightPoints = 0xFFFFU - 4;
702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
703aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
704aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* we arbitrarily limit recursion to avoid stack exhaustion */
705aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( maxProfile->maxComponentDepth > 100 )
706aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      {
707aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        FT_TRACE0(( "tt_face_load_maxp:"
708aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                    " abnormally large component depth (%d) set to 100\n",
709aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                    maxProfile->maxComponentDepth ));
710aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        maxProfile->maxComponentDepth = 100;
711aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      }
712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs ));
715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_load_names                                                 */
725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Loads the name records.                                            */
728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face   :: A handle to the target face object.                      */
731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream :: The input stream.                                        */
733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_name( TT_Face    face,
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream  stream )
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error      error;
742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory     memory = stream->memory;
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong      table_pos, table_len;
744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong      storage_start, storage_limit;
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt       count;
746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_NameTable  table;
747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static const FT_Frame_Field  name_table_fields[] =
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_STRUCTURE
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_STRUCTURE  TT_NameTableRec
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_START( 6 ),
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( format ),
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( numNameRecords ),
756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( storageOffset ),
757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_END
758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static const FT_Frame_Field  name_record_fields[] =
761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_STRUCTURE
763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_STRUCTURE  TT_NameEntryRec
764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* no FT_FRAME_START */
766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( platformID ),
767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( encodingID ),
768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( languageID ),
769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( nameID ),
770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( stringLength ),
771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( stringOffset ),
772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_END
773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table         = &face->name_table;
777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->stream = stream;
778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = face->goto_table( face, TTAG_name, stream, &table_len );
780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table_pos = FT_STREAM_POS();
784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_READ_FIELDS( name_table_fields, table ) )
787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Some popular Asian fonts have an invalid `storageOffset' value   */
790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* (it should be at least "6 + 12*num_names").  However, the string */
791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* offsets, computed as "storageOffset + entry->stringOffset", are  */
792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* valid pointers within the name table...                          */
793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                  */
794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* We thus can't check `storageOffset' right now.                   */
795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                  */
796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    storage_start = table_pos + 6 + 12*table->numNameRecords;
797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    storage_limit = table_pos + table_len;
798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( storage_start > storage_limit )
800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
801295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_ERROR(( "tt_face_load_name: invalid `name' table\n" ));
802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = SFNT_Err_Name_Table_Missing;
803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Allocate the array of name records. */
807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    count                 = table->numNameRecords;
808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->numNameRecords = 0;
809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW_ARRAY( table->names, count ) ||
811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_FRAME_ENTER( count * 12 )        )
812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Load the name records and determine how much storage is needed */
815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* to hold the strings themselves.                                */
816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TT_NameEntryRec*  entry = table->names;
818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; count > 0; count-- )
821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_STREAM_READ_FIELDS( name_record_fields, entry ) )
823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          continue;
824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* check that the name is not empty */
826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( entry->stringLength == 0 )
827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          continue;
828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* check that the name string is within the table */
830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        entry->stringOffset += table_pos + table->storageOffset;
831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( entry->stringOffset                       < storage_start ||
832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             entry->stringOffset + entry->stringLength > storage_limit )
833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* invalid entry - ignore it */
835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          entry->stringOffset = 0;
836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          entry->stringLength = 0;
837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          continue;
838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        entry++;
841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      table->numNameRecords = (FT_UInt)( entry - table->names );
844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FRAME_EXIT();
847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* everything went well, update face->num_names */
849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->num_names = (FT_UShort) table->numNameRecords;
850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_free_names                                                 */
860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Frees the name records.                                            */
863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face :: A handle to the target face object.                        */
866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_free_name( TT_Face  face )
869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory     memory = face->root.driver->root.memory;
871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_NameTable  table  = &face->name_table;
872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_NameEntry  entry  = table->names;
873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt       count  = table->numNameRecords;
874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( table->names )
877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; count > 0; count--, entry++ )
879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FREE( entry->string );
881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        entry->stringLength = 0;
882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* free strings table */
885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( table->names );
886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->numNameRecords = 0;
889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->format         = 0;
890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    table->storageOffset  = 0;
891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_load_cmap                                                  */
898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Loads the cmap directory in a face object.  The cmaps themselves   */
901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    are loaded on demand in the `ttcmap.c' module.                     */
902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face   :: A handle to the target face object.                      */
905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream :: A handle to the input stream.                            */
907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_cmap( TT_Face    face,
914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream  stream )
915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = face->goto_table( face, TTAG_cmap, stream, &face->cmap_size );
920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_FRAME_EXTRACT( face->cmap_size, face->cmap_table ) )
924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->cmap_size = 0;
925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_load_os2                                                   */
936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Loads the OS2 table.                                               */
939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face   :: A handle to the target face object.                      */
942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream :: A handle to the input stream.                            */
944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_os2( TT_Face    face,
950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Stream  stream )
951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_OS2*   os2;
954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const FT_Frame_Field  os2_fields[] =
956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_STRUCTURE
958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_STRUCTURE  TT_OS2
959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_START( 78 ),
961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( version ),
962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( xAvgCharWidth ),
963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( usWeightClass ),
964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( usWidthClass ),
965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( fsType ),
966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( ySubscriptXSize ),
967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( ySubscriptYSize ),
968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( ySubscriptXOffset ),
969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( ySubscriptYOffset ),
970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( ySuperscriptXSize ),
971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( ySuperscriptYSize ),
972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( ySuperscriptXOffset ),
973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( ySuperscriptYOffset ),
974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( yStrikeoutSize ),
975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( yStrikeoutPosition ),
976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( sFamilyClass ),
977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( panose[0] ),
978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( panose[1] ),
979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( panose[2] ),
980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( panose[3] ),
981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( panose[4] ),
982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( panose[5] ),
983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( panose[6] ),
984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( panose[7] ),
985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( panose[8] ),
986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( panose[9] ),
987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG ( ulUnicodeRange1 ),
988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG ( ulUnicodeRange2 ),
989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG ( ulUnicodeRange3 ),
990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG ( ulUnicodeRange4 ),
991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( achVendID[0] ),
992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( achVendID[1] ),
993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( achVendID[2] ),
994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( achVendID[3] ),
995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( fsSelection ),
997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( usFirstCharIndex ),
998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( usLastCharIndex ),
999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( sTypoAscender ),
1000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( sTypoDescender ),
1001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( sTypoLineGap ),
1002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( usWinAscent ),
1003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( usWinDescent ),
1004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_END
1005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
1006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const FT_Frame_Field  os2_fields_extra[] =
1008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_START( 8 ),
1010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG( ulCodePageRange1 ),
1011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG( ulCodePageRange2 ),
1012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_END
1013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
1014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const FT_Frame_Field  os2_fields_extra2[] =
1016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_START( 10 ),
1018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( sxHeight ),
1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT ( sCapHeight ),
1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( usDefaultChar ),
1021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( usBreakChar ),
1022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( usMaxContext ),
1023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_END
1024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* We now support old Mac fonts where the OS/2 table doesn't  */
1028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* exist.  Simply put, we set the `version' field to 0xFFFF   */
1029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* and test this value each time we need to access the table. */
1030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = face->goto_table( face, TTAG_OS2, stream, 0 );
1031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    os2 = &face->os2;
1035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_READ_FIELDS( os2_fields, os2 ) )
1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    os2->ulCodePageRange1 = 0;
1040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    os2->ulCodePageRange2 = 0;
1041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    os2->sxHeight         = 0;
1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    os2->sCapHeight       = 0;
1043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    os2->usDefaultChar    = 0;
1044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    os2->usBreakChar      = 0;
1045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    os2->usMaxContext     = 0;
1046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( os2->version >= 0x0001 )
1048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* only version 1 tables */
1050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_STREAM_READ_FIELDS( os2_fields_extra, os2 ) )
1051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( os2->version >= 0x0002 )
1054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* only version 2 tables */
1056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_STREAM_READ_FIELDS( os2_fields_extra2, os2 ) )
1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE3(( "sTypoAscender:  %4d\n",   os2->sTypoAscender ));
1062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE3(( "sTypoDescender: %4d\n",   os2->sTypoDescender ));
1063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE3(( "usWinAscent:    %4u\n",   os2->usWinAscent ));
1064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE3(( "usWinDescent:   %4u\n",   os2->usWinDescent ));
1065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE3(( "fsSelection:    0x%2x\n", os2->fsSelection ));
1066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
1075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_load_postscript                                            */
1076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
1078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Loads the Postscript table.                                        */
1079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face   :: A handle to the target face object.                      */
1082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream :: A handle to the input stream.                            */
1084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
1086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
1087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
1089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_post( TT_Face    face,
1090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream  stream )
1091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error        error;
1093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_Postscript*  post = &face->postscript;
1094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static const FT_Frame_Field  post_fields[] =
1096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_STRUCTURE
1098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_STRUCTURE  TT_Postscript
1099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_START( 32 ),
1101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG( FormatType ),
1102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG( italicAngle ),
1103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT( underlinePosition ),
1104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_SHORT( underlineThickness ),
1105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG( isFixedPitch ),
1106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG( minMemType42 ),
1107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG( maxMemType42 ),
1108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG( minMemType1 ),
1109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG( maxMemType1 ),
1110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_END
1111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
1112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = face->goto_table( face, TTAG_post, stream, 0 );
1115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
1117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_READ_FIELDS( post_fields, post ) )
1119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
1120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* we don't load the glyph names, we do that in another */
1122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* module (ttpost).                                     */
1123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE3(( "FormatType:   0x%x\n", post->FormatType ));
1125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE3(( "isFixedPitch:   %s\n", post->isFixedPitch
1126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                        ? "  yes" : "   no" ));
1127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return SFNT_Err_Ok;
1129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
1135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_load_pclt                                                  */
1136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
1138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Loads the PCL 5 Table.                                             */
1139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
1141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face   :: A handle to the target face object.                      */
1142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream :: A handle to the input stream.                            */
1144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
1146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
1147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
1149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_pclt( TT_Face    face,
1150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream  stream )
1151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static const FT_Frame_Field  pclt_fields[] =
1153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_STRUCTURE
1155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_STRUCTURE  TT_PCLT
1156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_START( 54 ),
1158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG ( Version ),
1159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_ULONG ( FontNumber ),
1160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( Pitch ),
1161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( xHeight ),
1162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( Style ),
1163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( TypeFamily ),
1164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_USHORT( CapHeight ),
1165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTES ( TypeFace, 16 ),
1166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTES ( CharacterComplement, 8 ),
1167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTES ( FileName, 6 ),
1168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_CHAR  ( StrokeWeight ),
1169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_CHAR  ( WidthType ),
1170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( SerifStyle ),
1171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FRAME_BYTE  ( Reserved ),
1172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FRAME_END
1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    };
1174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
1176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_PCLT*  pclt = &face->pclt;
1177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* optional table */
1180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = face->goto_table( face, TTAG_PCLT, stream, 0 );
1181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_READ_FIELDS( pclt_fields, pclt ) )
1185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
1195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_load_gasp                                                  */
1196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
1198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Loads the `gasp' table into a face object.                         */
1199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
1201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face   :: A handle to the target face object.                      */
1202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream :: The input stream.                                        */
1204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
1206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
1207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
1209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_gasp( TT_Face    face,
1210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream  stream )
1211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
1213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = stream->memory;
1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt        j,num_ranges;
1216c3ee10bfa1f76a18500b487de9c85757375b48f3David 'Digit' Turner    TT_GaspRange   gaspranges = NULL;
1217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the gasp table is optional */
1220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = face->goto_table( face, TTAG_gasp, stream, 0 );
1221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_FRAME_ENTER( 4L ) )
1225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->gasp.version   = FT_GET_USHORT();
1228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->gasp.numRanges = FT_GET_USHORT();
1229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FRAME_EXIT();
1231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* only support versions 0 and 1 of the table */
1233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->gasp.version >= 2 )
1234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->gasp.numRanges = 0;
1236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = SFNT_Err_Invalid_Table;
1237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    num_ranges = face->gasp.numRanges;
1241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE3(( "numRanges: %u\n", num_ranges ));
1242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_QNEW_ARRAY( gaspranges, num_ranges ) ||
1244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_FRAME_ENTER( num_ranges * 4L )      )
1245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->gasp.gaspRanges = gaspranges;
1248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( j = 0; j < num_ranges; j++ )
1250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gaspranges[j].maxPPEM  = FT_GET_USHORT();
1252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gaspranges[j].gaspFlag = FT_GET_USHORT();
1253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_TRACE3(( "gaspRange %d: rangeMaxPPEM %5d, rangeGaspBehavior 0x%x\n",
1255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  j,
1256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  gaspranges[j].maxPPEM,
1257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  gaspranges[j].gaspFlag ));
1258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FRAME_EXIT();
1261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
1268