ttpload.c revision 295ffce55e0198e7a9f7d46b33f5c2b4147bf821
1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  ttpload.c                                                              */
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*    TrueType-specific tables loader (body).                              */
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
7295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner/*  Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009 by       */
8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  This file is part of the FreeType project, and may only be used,       */
11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  modified, and distributed under the terms of the FreeType project      */
12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  this file you indicate that you have read the license and              */
14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  understand and accept it fully.                                        */
15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_OBJECTS_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
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ttpload.h"
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ttgxvar.h"
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "tterrors.h"
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* messages during execution.                                            */
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_ttpload
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_load_loca                                                  */
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Load the locations table.                                          */
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <InOut>                                                               */
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face   :: A handle to the target face object.                      */
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream :: The input stream.                                        */
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_loca( TT_Face    face,
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream  stream )
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong  table_len;
670a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_Int    shift;
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* we need the size of the `glyf' table for malformed `loca' tables */
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len );
720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
730a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* it is possible that a font doesn't have a glyf table at all */
740a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* or its size is zero                                         */
750a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( error == TT_Err_Table_Missing )
760a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      face->glyf_len = 0;
770a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    else if ( error )
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE2(( "Locations " ));
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = face->goto_table( face, TTAG_loca, stream, &table_len );
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = TT_Err_Locations_Missing;
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->header.Index_To_Loc_Format != 0 )
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
900a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      shift = 2;
910a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( table_len >= 0x40000L )
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
94295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_TRACE2(( "table too large\n" ));
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = TT_Err_Invalid_Table;
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
98295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      face->num_locations = table_len >> shift;
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1020a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      shift = 1;
1030a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( table_len >= 0x20000L )
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
106295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_TRACE2(( "table too large\n" ));
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = TT_Err_Invalid_Table;
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
110295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      face->num_locations = table_len >> shift;
1110a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
1120a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
113295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( face->num_locations != (FT_ULong)face->root.num_glyphs )
1140a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    {
1150a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_TRACE2(( "glyph count mismatch!  loca: %d, maxp: %d\n",
1160a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                  face->num_locations, face->root.num_glyphs ));
1170a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1180a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      /* we only handle the case where `maxp' gives a larger value */
119295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      if ( face->num_locations < (FT_ULong)face->root.num_glyphs )
1200a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      {
1210a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        FT_Long   new_loca_len = (FT_Long)face->root.num_glyphs << shift;
1220a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1230a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        TT_Table  entry = face->dir_tables;
1240a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        TT_Table  limit = entry + face->num_tables;
1250a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1260a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        FT_Long   pos  = FT_Stream_Pos( stream );
1270a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        FT_Long   dist = 0x7FFFFFFFL;
1280a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1290a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1300a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        /* compute the distance to next table in font file */
1310a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        for ( ; entry < limit; entry++ )
1320a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        {
1330a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          FT_Long  diff = entry->Offset - pos;
1340a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1350a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          if ( diff > 0 && diff < dist )
1370a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            dist = diff;
1380a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        }
1390a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1400a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        if ( new_loca_len <= dist )
1410a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        {
142295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          face->num_locations = face->root.num_glyphs;
1430a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          table_len           = new_loca_len;
1440a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1450a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          FT_TRACE2(( "adjusting num_locations to %d\n",
1460a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                      face->num_locations ));
1470a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        }
1480a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      }
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * Extract the frame.  We don't need to decompress it since
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * we are able to parse it directly.
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     */
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) )
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE2(( "loaded\n" ));
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_ULong )
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_get_location( TT_Face   face,
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_UInt   gindex,
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_UInt  *asize )
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong  pos1, pos2;
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p;
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p_limit;
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pos1 = pos2 = 0;
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( gindex < face->num_locations )
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( face->header.Index_To_Loc_Format != 0 )
180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p       = face->glyph_locations + gindex * 4;
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p_limit = face->glyph_locations + face->num_locations * 4;
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pos1 = FT_NEXT_ULONG( p );
185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pos2 = pos1;
186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( p + 4 <= p_limit )
188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          pos2 = FT_NEXT_ULONG( p );
189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p       = face->glyph_locations + gindex * 2;
193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        p_limit = face->glyph_locations + face->num_locations * 2;
194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pos1 = FT_NEXT_USHORT( p );
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pos2 = pos1;
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( p + 2 <= p_limit )
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          pos2 = FT_NEXT_USHORT( p );
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pos1 <<= 1;
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pos2 <<= 1;
203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
206295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* The `loca' table must be ordered; it refers to the length of */
207295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* an entry as the difference between the current and the next  */
208295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* position.  However, there do exist (malformed) fonts which   */
209295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* don't obey this rule, so we are only able to provide an      */
210295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* upper bound for the size.                                    */
2110a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /*                                                              */
2120a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* We get (intentionally) a wrong, non-zero result in case the  */
2130a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* `glyf' table is missing.                                     */
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pos2 >= pos1 )
215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *asize = (FT_UInt)( pos2 - pos1 );
216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *asize = (FT_UInt)( face->glyf_len - pos1 );
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return pos1;
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_done_loca( TT_Face  face )
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream  stream = face->root.stream;
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FRAME_RELEASE( face->glyph_locations );
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->num_locations = 0;
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_load_cvt                                                   */
239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Load the control value table into a face object.                   */
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <InOut>                                                               */
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face   :: A handle to the target face object.                      */
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream :: A handle to the input stream.                            */
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_cvt( TT_Face    face,
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Stream  stream )
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = stream->memory;
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong   table_len;
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE2(( "CVT " ));
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = face->goto_table( face, TTAG_cvt, stream, &table_len );
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
268295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_TRACE2(( "is missing\n" ));
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->cvt_size = 0;
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->cvt      = NULL;
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error          = TT_Err_Ok;
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->cvt_size = table_len / 2;
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW_ARRAY( face->cvt, face->cvt_size ) )
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_FRAME_ENTER( face->cvt_size * 2L ) )
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Short*  cur   = face->cvt;
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Short*  limit = cur + face->cvt_size;
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; cur <  limit; cur++ )
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *cur = FT_GET_SHORT();
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FRAME_EXIT();
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE2(( "loaded\n" ));
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->doblend )
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = tt_face_vary_cvt( face, stream );
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !TT_USE_BYTECODE_INTERPRETER */
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( face   );
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( stream );
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return TT_Err_Ok;
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_load_fpgm                                                  */
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Load the font program.                                             */
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <InOut>                                                               */
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face   :: A handle to the target face object.                      */
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream :: A handle to the input stream.                            */
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_fpgm( TT_Face    face,
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream  stream )
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong  table_len;
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE2(( "Font program " ));
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* The font program is optional */
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = face->goto_table( face, TTAG_fpgm, stream, &table_len );
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->font_program      = NULL;
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->font_program_size = 0;
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error                   = TT_Err_Ok;
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
353295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_TRACE2(( "is missing\n" ));
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->font_program_size = table_len;
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_FRAME_EXTRACT( table_len, face->font_program ) )
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size ));
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !TT_USE_BYTECODE_INTERPRETER */
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( face   );
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( stream );
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return TT_Err_Ok;
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_load_prep                                                  */
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Load the cvt program.                                              */
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <InOut>                                                               */
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face   :: A handle to the target face object.                      */
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream :: A handle to the input stream.                            */
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_prep( TT_Face    face,
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream  stream )
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong  table_len;
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE2(( "Prep program " ));
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = face->goto_table( face, TTAG_prep, stream, &table_len );
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->cvt_program      = NULL;
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->cvt_program_size = 0;
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error                  = TT_Err_Ok;
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
414295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_TRACE2(( "is missing\n" ));
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->cvt_program_size = table_len;
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_FRAME_EXTRACT( table_len, face->cvt_program ) )
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size ));
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !TT_USE_BYTECODE_INTERPRETER */
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( face   );
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( stream );
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return TT_Err_Ok;
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    tt_face_load_hdmx                                                  */
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Load the `hdmx' table into the face object.                        */
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    face   :: A handle to the target face object.                      */
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    stream :: A handle to the input stream.                            */
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_load_hdmx( TT_Face    face,
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream  stream )
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = stream->memory;
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt    version, nn, num_records;
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong   table_size, record_size;
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*   p;
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*   limit;
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* this table is optional */
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = face->goto_table( face, TTAG_hdmx, stream, &table_size );
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error || table_size < 8 )
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return TT_Err_Ok;
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_FRAME_EXTRACT( table_size, face->hdmx_table ) )
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    p     = face->hdmx_table;
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    limit = p + table_size;
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    version     = FT_NEXT_USHORT( p );
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    num_records = FT_NEXT_USHORT( p );
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    record_size = FT_NEXT_ULONG( p );
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* The maximum number of bytes in an hdmx device record is the */
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is   */
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the reason why `record_size' is a long (which we read as    */
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* unsigned long for convenience).  In practice, two bytes     */
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* sufficient to hold the size value.                          */
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                             */
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* There are at least two fonts, HANNOM-A and HANNOM-B version */
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* 2.0 (2005), which get this wrong: The upper two bytes of    */
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the size value are set to 0xFF instead of 0x00.  We catch   */
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* and fix this.                                               */
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( record_size >= 0xFFFF0000UL )
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      record_size &= 0xFFFFU;
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* The limit for `num_records' is a heuristic value. */
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( version != 0 || num_records > 255 || record_size > 0x10001L )
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = TT_Err_Invalid_File_Format;
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW_ARRAY( face->hdmx_record_sizes, num_records ) )
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( nn = 0; nn < num_records; nn++ )
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( p + record_size > limit )
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->hdmx_record_sizes[nn] = p[0];
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p                          += record_size;
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->hdmx_record_count = nn;
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->hdmx_table_size   = table_size;
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->hdmx_record_size  = record_size;
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FRAME_RELEASE( face->hdmx_table );
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->hdmx_table_size = 0;
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_free_hdmx( TT_Face  face )
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream  stream = face->root.stream;
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = stream->memory;
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( face->hdmx_record_sizes );
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FRAME_RELEASE( face->hdmx_table );
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Return the advance width table for a given pixel size if it is found  */
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* in the font's `hdmx' table (if any).                                  */
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Byte* )
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_face_get_device_metrics( TT_Face  face,
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              FT_UInt  ppem,
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              FT_UInt  gindex )
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt   nn;
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  result      = NULL;
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong  record_size = face->hdmx_record_size;
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  record      = face->hdmx_table + 8;
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( nn = 0; nn < face->hdmx_record_count; nn++ )
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( face->hdmx_record_sizes[nn] == ppem )
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gindex += 2;
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( gindex < record_size )
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result = record + nn * record_size + gindex;
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
573