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