1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  ftobjs.c                                                               */
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*    The FreeType private base classes (body).                            */
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
741371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier/*  Copyright 1996-2012 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_LIST_H
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_OUTLINE_H
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_VALIDATE_H
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_OBJECTS_H
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_RFORK_H
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_STREAM_H
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_SFNT_H    /* for SFNT_Load_Table_Func */
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_TRUETYPE_TABLES_H
2977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#include FT_TRUETYPE_TAGS_H
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_TRUETYPE_IDS_H
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_SERVICE_SFNT_H
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_SERVICE_POSTSCRIPT_NAME_H
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_SERVICE_GLYPH_DICT_H
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_SERVICE_TT_CMAP_H
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_SERVICE_KERNING_H
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_SERVICE_TRUETYPE_ENGINE_H
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
39295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifdef FT_CONFIG_OPTION_MAC_FONTS
4077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#include "ftbase.h"
41295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define GRID_FIT_METRICS
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Pointer )
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_service_list_lookup( FT_ServiceDesc  service_descriptors,
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          const char*     service_id )
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pointer      result = NULL;
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ServiceDesc  desc   = service_descriptors;
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( desc && service_id )
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; desc->serv_id != NULL; desc++ )
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ft_strcmp( desc->serv_id, service_id ) == 0 )
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result = (FT_Pointer)desc->serv_data;
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_validator_init( FT_Validator        valid,
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     const FT_Byte*      base,
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     const FT_Byte*      limit,
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_ValidationLevel  level )
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    valid->base  = base;
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    valid->limit = limit;
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    valid->level = level;
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    valid->error = FT_Err_Ok;
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Int )
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_validator_run( FT_Validator  valid )
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* This function doesn't work!  None should call it. */
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( valid );
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return -1;
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_validator_error( FT_Validator  valid,
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Error      error )
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* since the cast below also disables the compiler's */
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* type check, we introduce a dummy variable, which  */
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* will be optimized away                            */
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    volatile ft_jmp_buf* jump_buffer = &valid->jump_buffer;
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    valid->error = error;
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* throw away volatileness; use `jump_buffer' or the  */
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* compiler may warn about an unused local variable   */
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_longjmp( *(ft_jmp_buf*) jump_buffer, 1 );
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                           S T R E A M                           ****/
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* create a new input stream from an FT_Open_Args structure */
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                          */
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_New( FT_Library           library,
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const FT_Open_Args*  args,
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Stream           *astream )
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory;
133aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_Stream  stream = NULL;
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
13677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    *astream = 0;
13777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Library_Handle;
140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !args )
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Argument;
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
144aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    memory = library->memory;
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( stream ) )
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->memory = memory;
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( args->flags & FT_OPEN_MEMORY )
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* create a memory-based stream */
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_OpenMemory( stream,
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            (const FT_Byte*)args->memory_base,
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            args->memory_size );
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
158aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
159aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT
160aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( args->flags & FT_OPEN_PATHNAME )
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* create a normal system stream */
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Stream_Open( stream, args->pathname );
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->pathname.pointer = args->pathname;
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream )
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* use an existing, user-provided stream */
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* in this case, we do not need to allocate a new stream object */
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* since the caller is responsible for closing it himself       */
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( stream );
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream = args->stream;
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
176aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
177aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif
178aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Err_Invalid_Argument;
181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( stream );
184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->memory = memory;  /* just to be certain */
186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *astream = stream;
188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_Free( FT_Stream  stream,
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Int     external )
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream )
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Memory  memory = stream->memory;
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_Close( stream );
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !external )
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FREE( stream );
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
21177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /*************************************************************************/
21277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /*                                                                       */
21377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
21477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
21577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* messages during execution.                                            */
21677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /*                                                                       */
217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_objs
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****               FACE, SIZE & GLYPH SLOT OBJECTS                   ****/
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_init( FT_GlyphSlot  slot )
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
237aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Driver         driver   = slot->face->driver;
238aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Driver_Class   clazz    = driver->clazz;
239aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Memory         memory   = driver->root.memory;
240aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Error          error    = FT_Err_Ok;
241aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Slot_Internal  internal = NULL;
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->library = driver->root.library;
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( internal ) )
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->internal = internal;
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_DRIVER_USES_OUTLINES( driver ) )
252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_GlyphLoader_New( memory, &internal->loader );
253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error && clazz->init_slot )
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = clazz->init_slot( slot );
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_free_bitmap( FT_GlyphSlot  slot )
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
26577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Memory  memory = FT_FACE_MEMORY( slot->face );
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( slot->bitmap.buffer );
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* assume that the bitmap buffer was stolen or not */
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* allocated from the heap                         */
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->bitmap.buffer = NULL;
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_set_bitmap( FT_GlyphSlot  slot,
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_Byte*      buffer )
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_glyphslot_free_bitmap( slot );
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap.buffer = buffer;
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( (slot->internal->flags & FT_GLYPH_OWN_BITMAP) == 0 );
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_alloc_bitmap( FT_GlyphSlot  slot,
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             FT_ULong      size )
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = FT_FACE_MEMORY( slot->face );
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( slot->bitmap.buffer );
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (void)FT_ALLOC( slot->bitmap.buffer, size );
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_clear( FT_GlyphSlot  slot )
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* free bitmap if needed */
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_glyphslot_free_bitmap( slot );
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* clear all public fields in the glyph slot */
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ZERO( &slot->metrics );
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ZERO( &slot->outline );
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap.width      = 0;
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap.rows       = 0;
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap.pitch      = 0;
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap.pixel_mode = 0;
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* `slot->bitmap.buffer' has been handled by ft_glyphslot_free_bitmap */
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap_left   = 0;
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap_top    = 0;
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->num_subglyphs = 0;
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->subglyphs     = 0;
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->control_data  = 0;
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->control_len   = 0;
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->other         = 0;
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->format        = FT_GLYPH_FORMAT_NONE;
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->linearHoriAdvance = 0;
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->linearVertAdvance = 0;
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->lsb_delta         = 0;
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->rsb_delta         = 0;
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_done( FT_GlyphSlot  slot )
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver        driver = slot->face->driver;
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz  = driver->clazz;
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory        memory = driver->root.memory;
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->done_slot )
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      clazz->done_slot( slot );
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* free bitmap buffer if needed */
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_glyphslot_free_bitmap( slot );
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
358295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* slot->internal might be NULL in out-of-memory situations */
359295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( slot->internal )
360295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    {
361aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* free glyph loader */
362aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( FT_DRIVER_USES_OUTLINES( driver ) )
363aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      {
364aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        FT_GlyphLoader_Done( slot->internal->loader );
365aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        slot->internal->loader = 0;
366aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      }
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
368aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_FREE( slot->internal );
369295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    }
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_New_GlyphSlot( FT_Face        face,
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_GlyphSlot  *aslot )
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error         error;
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver        driver;
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz;
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory        memory;
383aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_GlyphSlot     slot = NULL;
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face || !face->driver )
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Argument;
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    driver = face->driver;
390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clazz  = driver->clazz;
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = driver->root.memory;
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" ));
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_ALLOC( slot, clazz->slot_object_size ) )
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->face = face;
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = ft_glyphslot_init( slot );
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ft_glyphslot_done( slot );
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FREE( slot );
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->next  = face->glyph;
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->glyph = slot;
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( aslot )
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *aslot = slot;
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( aslot )
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *aslot = 0;
414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error ));
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Done_GlyphSlot( FT_GlyphSlot  slot )
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( slot )
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Driver     driver = slot->face->driver;
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Memory     memory = driver->root.memory;
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphSlot  prev;
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphSlot  cur;
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Remove slot from its parent face's list */
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      prev = NULL;
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur  = slot->face->glyph;
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( cur )
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( cur == slot )
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( !prev )
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            slot->face->glyph = cur->next;
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          else
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            prev->next = cur->next;
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
44841371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier          /* finalize client-specific data */
44941371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier          if ( slot->generic.finalizer )
45041371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier            slot->generic.finalizer( slot );
45141371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ft_glyphslot_done( slot );
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_FREE( slot );
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        prev = cur;
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cur  = cur->next;
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Set_Transform( FT_Face     face,
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Matrix*  matrix,
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Vector*  delta )
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face_Internal  internal;
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    internal = face->internal;
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    internal->transform_flags = 0;
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !matrix )
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.xx = 0x10000L;
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.xy = 0;
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.yx = 0;
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.yy = 0x10000L;
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      matrix = &internal->transform_matrix;
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix = *matrix;
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* set transform_flags bit flag 0 if `matrix' isn't the identity */
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ( matrix->xy | matrix->yx ) ||
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         matrix->xx != 0x10000L      ||
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         matrix->yy != 0x10000L      )
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_flags |= 1;
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !delta )
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_delta.x = 0;
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_delta.y = 0;
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta = &internal->transform_delta;
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_delta = *delta;
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* set transform_flags bit flag 1 if `delta' isn't the null vector */
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( delta->x | delta->y )
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_flags |= 2;
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Renderer
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_lookup_glyph_renderer( FT_GlyphSlot  slot );
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef GRID_FIT_METRICS
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_grid_fit_metrics( FT_GlyphSlot  slot,
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 FT_Bool       vertical )
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Glyph_Metrics*  metrics = &slot->metrics;
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pos             right, bottom;
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( vertical )
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX );
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY );
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      right  = FT_PIX_CEIL( metrics->vertBearingX + metrics->width );
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bottom = FT_PIX_CEIL( metrics->vertBearingY + metrics->height );
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->width  = right - metrics->vertBearingX;
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->height = bottom - metrics->vertBearingY;
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      right  = FT_PIX_CEIL ( metrics->horiBearingX + metrics->width );
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bottom = FT_PIX_FLOOR( metrics->horiBearingY - metrics->height );
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX );
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY );
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->width  = right - metrics->horiBearingX;
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->height = metrics->horiBearingY - bottom;
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance );
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance );
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* GRID_FIT_METRICS */
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Load_Glyph( FT_Face   face,
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_UInt   glyph_index,
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Int32  load_flags )
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error      error;
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver     driver;
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphSlot  slot;
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Library    library;
57177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Bool       autohint = FALSE;
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module     hinter;
573aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    TT_Face       ttface = (TT_Face)face;
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face || !face->size || !face->glyph )
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Face_Handle;
578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* The validity test for `glyph_index' is performed by the */
580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* font drivers.                                           */
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot = face->glyph;
583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_glyphslot_clear( slot );
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    driver  = face->driver;
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library = driver->root.library;
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hinter  = library->auto_hinter;
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* resolve load flags dependencies */
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( load_flags & FT_LOAD_NO_RECURSE )
592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      load_flags |= FT_LOAD_NO_SCALE         |
593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_LOAD_IGNORE_TRANSFORM;
594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( load_flags & FT_LOAD_NO_SCALE )
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      load_flags |= FT_LOAD_NO_HINTING |
598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_LOAD_NO_BITMAP;
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      load_flags &= ~FT_LOAD_RENDER;
601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*
604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * Determine whether we need to auto-hint or not.
605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * The general rules are:
606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
607295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     * - Do only auto-hinting if we have a hinter module, a scalable font
608295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     *   format dealing with outlines, and no transforms except simple
609295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     *   slants and/or rotations by integer multiples of 90 degrees.
610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
611295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't
612295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     *   have a native font hinter.
613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
614aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner     * - Otherwise, auto-hint for LIGHT hinting mode or if there isn't
615aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner     *   any hinting bytecode in the TrueType/OpenType font.
616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
617295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     * - Exception: The font is `tricky' and requires the native hinter to
618295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     *   load properly.
619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     */
620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
621aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( hinter                                           &&
622aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         !( load_flags & FT_LOAD_NO_HINTING )             &&
623aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         !( load_flags & FT_LOAD_NO_AUTOHINT )            &&
624aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         FT_DRIVER_IS_SCALABLE( driver )                  &&
625aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         FT_DRIVER_USES_OUTLINES( driver )                &&
626aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         !FT_IS_TRICKY( face )                            &&
627bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly         ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM )    ||
628bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly           ( face->internal->transform_matrix.yx == 0 &&
629295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner             face->internal->transform_matrix.xx != 0 ) ||
630295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner           ( face->internal->transform_matrix.xx == 0 &&
631295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner             face->internal->transform_matrix.yx != 0 ) ) )
63277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    {
63377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) ||
63477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner           !FT_DRIVER_HAS_HINTER( driver )         )
63577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        autohint = TRUE;
636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Render_Mode  mode = FT_LOAD_TARGET_MODE( load_flags );
639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
641aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        /* the check for `num_locations' assures that we actually    */
642aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        /* test for instructions in a TTF and not in a CFF-based OTF */
643aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        if ( mode == FT_RENDER_MODE_LIGHT                       ||
644aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner             face->internal->ignore_unpatented_hinter           ||
645aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner             ( FT_IS_SFNT( face )                             &&
646aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner               ttface->num_locations                          &&
647aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner               ttface->max_profile.maxSizeOfInstructions == 0 ) )
64877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          autohint = TRUE;
649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( autohint )
653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_AutoHinter_Service  hinting;
655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* try to load embedded bitmaps first if available            */
658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*                                                            */
659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* XXX: This is really a temporary hack that should disappear */
660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*      promptly with FreeType 2.1!                           */
661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*                                                            */
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_HAS_FIXED_SIZES( face )             &&
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = driver->clazz->load_glyph( slot, face->size,
666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           glyph_index,
667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           load_flags | FT_LOAD_SBITS_ONLY );
668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !error && slot->format == FT_GLYPH_FORMAT_BITMAP )
670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Load_Ok;
671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Face_Internal  internal        = face->internal;
675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int            transform_flags = internal->transform_flags;
676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* since the auto-hinter calls FT_Load_Glyph by itself, */
679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* make sure that glyphs aren't transformed             */
680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        internal->transform_flags = 0;
681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* load auto-hinted outline */
683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        hinting = (FT_AutoHinter_Service)hinter->clazz->module_interface;
684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error   = hinting->load_glyph( (FT_AutoHinter)hinter,
686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       slot, face->size,
687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       glyph_index, load_flags );
688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        internal->transform_flags = transform_flags;
690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = driver->clazz->load_glyph( slot,
695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                         face->size,
696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                         glyph_index,
697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                         load_flags );
698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* check that the loaded outline is correct */
704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = FT_Outline_Check( &slot->outline );
705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef GRID_FIT_METRICS
709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !( load_flags & FT_LOAD_NO_HINTING ) )
710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ft_glyphslot_grid_fit_metrics( slot,
711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              FT_BOOL( load_flags & FT_LOAD_VERTICAL_LAYOUT ) );
712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Load_Ok:
717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* compute the advance */
718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->advance.x = 0;
721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->advance.y = slot->metrics.vertAdvance;
722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->advance.x = slot->metrics.horiAdvance;
726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->advance.y = 0;
727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* compute the linear advance in 16.16 pixels */
730aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 &&
731aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         ( FT_IS_SCALABLE( face ) )                  )
732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Size_Metrics*  metrics = &face->size->metrics;
734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* it's tricky! */
737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance,
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           metrics->x_scale, 64 );
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->linearVertAdvance = FT_MulDiv( slot->linearVertAdvance,
741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           metrics->y_scale, 64 );
742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) == 0 )
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Face_Internal  internal = face->internal;
747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* now, transform the glyph image if needed */
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( internal->transform_flags )
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* get renderer */
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Renderer  renderer = ft_lookup_glyph_renderer( slot );
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( renderer )
757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          error = renderer->clazz->transform_glyph(
758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                     renderer, slot,
759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                     &internal->transform_matrix,
760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                     &internal->transform_delta );
761295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
762295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
763295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          /* apply `standard' transformation if no renderer is available */
764bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          if ( internal->transform_flags & 1 )
765295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            FT_Outline_Transform( &slot->outline,
766295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                  &internal->transform_matrix );
767295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
768bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          if ( internal->transform_flags & 2 )
769295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            FT_Outline_Translate( &slot->outline,
770295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                  internal->transform_delta.x,
771295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                  internal->transform_delta.y );
772295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
773295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* transform advance */
775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Vector_Transform( &slot->advance, &internal->transform_matrix );
776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
779295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_TRACE5(( "  x advance: %d\n" , slot->advance.x ));
780295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_TRACE5(( "  y advance: %d\n" , slot->advance.y ));
781295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
782295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_TRACE5(( "  linear x advance: %d\n" , slot->linearHoriAdvance ));
783295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_TRACE5(( "  linear y advance: %d\n" , slot->linearVertAdvance ));
784295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* do we need to render the image now? */
786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error                                    &&
787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         slot->format != FT_GLYPH_FORMAT_BITMAP    &&
788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         slot->format != FT_GLYPH_FORMAT_COMPOSITE &&
789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         load_flags & FT_LOAD_RENDER )
790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Render_Mode  mode = FT_LOAD_TARGET_MODE( load_flags );
792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( mode == FT_RENDER_MODE_NORMAL      &&
795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           (load_flags & FT_LOAD_MONOCHROME ) )
796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        mode = FT_RENDER_MODE_MONO;
797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Render_Glyph( slot, mode );
799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Load_Char( FT_Face   face,
810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_ULong  char_code,
811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Int32  load_flags )
812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  glyph_index;
814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Face_Handle;
818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    glyph_index = (FT_UInt)char_code;
820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->charmap )
821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph_index = FT_Get_Char_Index( face, char_code );
822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Load_Glyph( face, glyph_index, load_flags );
824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* destructor for sizes list */
828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  destroy_size( FT_Memory  memory,
830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Size    size,
831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Driver  driver )
832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* finalize client-specific data */
834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( size->generic.finalizer )
835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      size->generic.finalizer( size );
836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* finalize format-specific stuff */
838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( driver->clazz->done_size )
839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      driver->clazz->done_size( size );
840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( size->internal );
842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( size );
843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_cmap_done_internal( FT_CMap  cmap );
848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  destroy_charmaps( FT_Face    face,
852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Memory  memory )
853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int  n;
855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( n = 0; n < face->num_charmaps; n++ )
861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CMap  cmap = FT_CMAP( face->charmaps[n] );
863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_cmap_done_internal( cmap );
866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->charmaps[n] = NULL;
868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( face->charmaps );
871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->num_charmaps = 0;
872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* destructor for faces list */
876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  destroy_face( FT_Memory  memory,
878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Face    face,
879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Driver  driver )
880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz = driver->clazz;
882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* discard auto-hinting data */
885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->autohint.finalizer )
886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->autohint.finalizer( face->autohint.data );
887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Discard glyph slots for this face.                           */
889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Beware!  FT_Done_GlyphSlot() changes the field `face->glyph' */
890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( face->glyph )
891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Done_GlyphSlot( face->glyph );
892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* discard all sizes for this face */
894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_List_Finalize( &face->sizes_list,
895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      (FT_List_Destructor)destroy_size,
896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      memory,
897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      driver );
898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->size = 0;
899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* now discard client data */
901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->generic.finalizer )
902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->generic.finalizer( face );
903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* discard charmaps */
905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    destroy_charmaps( face, memory );
906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* finalize format-specific stuff */
908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->done_face )
909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      clazz->done_face( face );
910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* close the stream for this face if needed */
912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream_Free(
913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->stream,
914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->stream = 0;
917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* get rid of it */
919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->internal )
920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( face->internal );
922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( face );
924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Destroy_Driver( FT_Driver  driver )
929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_List_Finalize( &driver->faces_list,
931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      (FT_List_Destructor)destroy_face,
932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      driver->root.memory,
933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      driver );
934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check whether we need to drop the driver's glyph loader */
936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_DRIVER_USES_OUTLINES( driver ) )
937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphLoader_Done( driver->glyph_loader );
938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    find_unicode_charmap                                               */
945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    This function finds a Unicode charmap, if there is one.            */
948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    And if there is more than one, it tries to favour the more         */
949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    extensive one, i.e., one that supports UCS-4 against those which   */
950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    are limited to the BMP (said UCS-2 encoding.)                      */
951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    This function is called from open_face() (just below), and also    */
953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ).                */
954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  find_unicode_charmap( FT_Face  face )
957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  first;
959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  cur;
960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* caller should have already checked that `face' is valid */
963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( face );
964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    first = face->charmaps;
966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !first )
968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_CharMap_Handle;
969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*
971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  The original TrueType specification(s) only specified charmap
972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  formats that are capable of mapping 8 or 16 bit character codes to
973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  glyph indices.
974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  However, recent updates to the Apple and OpenType specifications
976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  introduced new formats that are capable of mapping 32-bit character
977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  codes as well.  And these are already used on some fonts, mainly to
978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  map non-BMP Asian ideographs as defined in Unicode.
979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  For compatibility purposes, these fonts generally come with
981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  *several* Unicode charmaps:
982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *   - One of them in the "old" 16-bit format, that cannot access
984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *     all glyphs in the font.
985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *   - Another one in the "new" 32-bit format, that can access all
987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *     the glyphs.
988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  This function has been written to always favor a 32-bit charmap
990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  when found.  Otherwise, a 16-bit one is returned when found.
991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     */
992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Since the `interesting' table, with IDs (3,10), is normally the */
994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* last one, we loop backwards.  This loses with type1 fonts with  */
995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* non-BMP characters (<.0001%), this wins with .ttf with non-BMP  */
996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* chars (.01% ?), and this is the same about 99.99% of the time!  */
997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur = first + face->num_charmaps;  /* points after the last one */
999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; --cur >= first; )
1001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur[0]->encoding == FT_ENCODING_UNICODE )
1003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* XXX If some new encodings to represent UCS-4 are added, */
1005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /*     they should be added here.                          */
1006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT &&
1007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               cur[0]->encoding_id == TT_MS_ID_UCS_4        )     ||
1008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE &&
1009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32    ) )
1010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1011aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE
1012aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )
1013aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          {
1014aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            FT_ERROR(( "find_unicode_charmap: UCS-4 cmap is found "
1015aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                       "at too late position (%d)\n", cur - first ));
1016aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            continue;
1017aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          }
1018aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          face->charmap = cur[0];
1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return FT_Err_Ok;
1021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* We do not have any UCS-4 charmap.                */
1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Do the loop again and search for UCS-2 charmaps. */
1027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur = first + face->num_charmaps;
1028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; --cur >= first; )
1030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur[0]->encoding == FT_ENCODING_UNICODE )
1032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1033aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE
1034aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )
1035aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
1036aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_ERROR(( "find_unicode_charmap: UCS-2 cmap is found "
1037aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                     "at too late position (%d)\n", cur - first ));
1038aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          continue;
1039aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        }
1040aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
1041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->charmap = cur[0];
1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return FT_Err_Ok;
1043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Invalid_CharMap_Handle;
1047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
1053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    find_variant_selector_charmap                                      */
1054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
1056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    This function finds the variant selector charmap, if there is one. */
1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    There can only be one (platform=0, specific=5, format=14).         */
1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_CharMap
1060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  find_variant_selector_charmap( FT_Face  face )
1061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  first;
1063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  end;
1064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  cur;
1065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* caller should have already checked that `face' is valid */
1068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( face );
1069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    first = face->charmaps;
1071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !first )
1073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return NULL;
1074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    end = first + face->num_charmaps;  /* points after the last one */
1076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( cur = first; cur < end; ++cur )
1078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE    &&
1080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR &&
1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           FT_Get_CMap_Format( cur[0] ) == 14                  )
10827f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      {
1083aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE
1084aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )
1085aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
1086aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_ERROR(( "find_unicode_charmap: UVS cmap is found "
1087aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                     "at too late position (%d)\n", cur - first ));
1088aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          continue;
1089aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        }
1090aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
1091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return cur[0];
10927f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      }
1093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return NULL;
1096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
1102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    open_face                                                          */
1103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
1105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    This function does some work for FT_Open_Face().                   */
1106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  open_face( FT_Driver      driver,
1109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Stream      stream,
1110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Long        face_index,
1111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Int         num_params,
1112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Parameter*  params,
1113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Face       *aface )
1114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory         memory;
1116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class   clazz;
1117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face           face = 0;
1118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error          error, error2;
1119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face_Internal  internal = NULL;
1120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clazz  = driver->clazz;
1123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = driver->root.memory;
1124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* allocate the face object and perform basic initialization */
1126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( face, clazz->face_object_size ) )
1127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
1128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( internal ) )
1130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
1131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->internal = internal;
1133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->driver   = driver;
1135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->memory   = memory;
1136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->stream   = stream;
1137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_CONFIG_OPTION_INCREMENTAL
1139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      int  i;
1141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->internal->incremental_interface = 0;
1144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( i = 0; i < num_params && !face->internal->incremental_interface;
1145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            i++ )
1146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL )
1147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          face->internal->incremental_interface =
1148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            (FT_Incremental_Interface)params[i].data;
1149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
1151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->init_face )
1153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = clazz->init_face( stream,
1154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                face,
1155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                (FT_Int)face_index,
1156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                num_params,
1157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                params );
1158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
1160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* select Unicode charmap by default */
1162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error2 = find_unicode_charmap( face );
1163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if no Unicode charmap can be found, FT_Err_Invalid_CharMap_Handle */
1165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* is returned.                                                      */
1166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* no error should happen, but we want to play safe */
1168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error2 && error2 != FT_Err_Invalid_CharMap_Handle )
1169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = error2;
1171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
1172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *aface = face;
1175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
1177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      destroy_charmaps( face, memory );
1180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( clazz->done_face )
1181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        clazz->done_face( face );
1182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( internal );
1183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( face );
1184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *aface = 0;
1185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* there's a Mac-specific extended implementation of FT_New_Face() */
1192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* in src/base/ftmac.c                                             */
1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
119441371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#ifndef FT_MACINTOSH
1195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
1197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
1199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_New_Face( FT_Library   library,
1200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               const char*  pathname,
1201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Long      face_index,
1202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Face     *aface )
1203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Open_Args  args;
1205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `library' and `aface' delayed to FT_Open_Face() */
1208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !pathname )
1209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Argument;
1210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.flags    = FT_OPEN_PATHNAME;
1212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.pathname = (char*)pathname;
121377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    args.stream   = NULL;
1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Open_Face( library, &args, face_index, aface );
1216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
121841371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#endif
1219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
1222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
1224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_New_Memory_Face( FT_Library      library,
1225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      const FT_Byte*  file_base,
1226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Long         file_size,
1227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Long         face_index,
1228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Face        *aface )
1229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Open_Args  args;
1231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `library' and `face' delayed to FT_Open_Face() */
1234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !file_base )
1235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Argument;
1236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.flags       = FT_OPEN_MEMORY;
1238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.memory_base = file_base;
1239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.memory_size = file_size;
124077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    args.stream      = NULL;
1241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Open_Face( library, &args, face_index, aface );
1243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
124677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#ifdef FT_CONFIG_OPTION_MAC_FONTS
1247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The behavior here is very similar to that in base/ftmac.c, but it     */
1249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* is designed to work on non-mac systems, so no mac specific calls.     */
1250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* We look at the file and determine if it is a mac dfont file or a mac  */
1252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* resource file, or a macbinary file containing a mac resource file.    */
1253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Unlike ftmac I'm not going to look at a `FOND'.  I don't really see   */
1255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* the point, especially since there may be multiple `FOND' resources.   */
1256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Instead I'll just look for `sfnt' and `POST' resources, ordered as    */
1257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* they occur in the file.                                               */
1258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Note that multiple `POST' resources do not mean multiple postscript   */
1260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* fonts; they all get jammed together to make what is essentially a     */
1261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* pfb file.                                                             */
1262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* We aren't interested in `NFNT' or `FONT' bitmap resources.            */
1264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* As soon as we get an `sfnt' load it into memory and pass it off to    */
1266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* FT_Open_Face.                                                         */
1267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* If we have a (set of) `POST' resources, massage them into a (memory)  */
1269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* pfb file and pass that to FT_Open_Face.  (As with ftmac.c I'm not     */
1270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* going to try to save the kerning info.  After all that lives in the   */
1271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* `FOND' which isn't in the file containing the `POST' resources so     */
1272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* we don't really have access to it.                                    */
1273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
127577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* Finalizer for a memory stream; gets called by FT_Done_Face(). */
127677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* It frees the memory it uses.                                  */
127777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* From ftmac.c.                                                 */
1278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  memory_stream_close( FT_Stream  stream )
1280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = stream->memory;
1282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( stream->base );
1285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->size  = 0;
1287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->base  = 0;
1288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->close = 0;
1289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Create a new memory stream from a buffer and a size. */
129377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* From ftmac.c.                                        */
1294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  new_memory_stream( FT_Library           library,
1296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Byte*             base,
1297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_ULong             size,
1298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream_CloseFunc  close,
1299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream           *astream )
1300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
1302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory;
1303aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_Stream  stream = NULL;
1304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
1307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Library_Handle;
1308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !base )
1310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Argument;
1311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *astream = 0;
1313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = library->memory;
1314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( stream ) )
1315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream_OpenMemory( stream, base, size );
1318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->close = close;
1320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *astream = stream;
1322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Create a new FT_Face given a buffer and a driver name. */
1329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* from ftmac.c */
133077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  FT_LOCAL_DEF( FT_Error )
1331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  open_face_from_buffer( FT_Library   library,
1332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Byte*     base,
1333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_ULong     size,
1334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Long      face_index,
1335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         const char*  driver_name,
1336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Face     *aface )
1337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Open_Args  args;
1339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error      error;
1340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream     stream = NULL;
1341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory     memory = library->memory;
1342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = new_memory_stream( library,
1345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               base,
1346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               size,
1347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               memory_stream_close,
1348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               &stream );
1349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( base );
1352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
1353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.flags = FT_OPEN_STREAM;
1356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.stream = stream;
1357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( driver_name )
1358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      args.flags = args.flags | FT_OPEN_DRIVER;
1360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      args.driver = FT_Get_Module( library, driver_name );
1361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
136377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#ifdef FT_MACINTOSH
136477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* At this point, face_index has served its purpose;      */
136577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* whoever calls this function has already used it to     */
136677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* locate the correct font data.  We should not propagate */
136777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* this index to FT_Open_Face() (unless it is negative).  */
136877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
136977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( face_index > 0 )
137077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      face_index = 0;
137177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#endif
137277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
1373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Open_Face( library, &args, face_index, aface );
1374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error == FT_Err_Ok )
1376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
1377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
137877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#ifdef FT_MACINTOSH
137977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      FT_Stream_Free( stream, 0 );
138077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#else
1381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_Close( stream );
1383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( stream );
1384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
138577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#endif
1386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
139177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* Look up `TYP1' or `CID ' table from sfnt table directory.       */
139277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* `offset' and `length' must exclude the binary header in tables. */
139377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
139477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */
139577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* format too.  Here, since we can't expect that the TrueType font */
139677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* driver is loaded unconditially, we must parse the font by       */
139777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* ourselves.  We are only interested in the name of the table and */
139877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* the offset.                                                     */
139977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
140077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  static FT_Error
140177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  ft_lookup_PS_in_sfnt_stream( FT_Stream  stream,
140277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                               FT_Long    face_index,
140377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                               FT_ULong*  offset,
140477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                               FT_ULong*  length,
140577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                               FT_Bool*   is_sfnt_cid )
140677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  {
140777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Error   error;
140877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_UShort  numTables;
140977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Long    pstable_index;
141077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_ULong   tag;
141177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    int        i;
141277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
141377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
141477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    *offset = 0;
141577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    *length = 0;
141677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    *is_sfnt_cid = FALSE;
141777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
141877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* TODO: support for sfnt-wrapped PS/CID in TTC format */
141977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
142077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* version check for 'typ1' (should be ignored?) */
142177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( FT_READ_ULONG( tag ) )
142277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      return error;
142377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( tag != TTAG_typ1 )
142477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      return FT_Err_Unknown_File_Format;
142577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
142677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( FT_READ_USHORT( numTables ) )
142777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      return error;
142877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( FT_STREAM_SKIP( 2 * 3 ) ) /* skip binary search header */
142977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      return error;
143077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
143177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    pstable_index = -1;
143277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    *is_sfnt_cid  = FALSE;
143377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
143477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    for ( i = 0; i < numTables; i++ )
143577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    {
143677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      if ( FT_READ_ULONG( tag )     || FT_STREAM_SKIP( 4 )      ||
143777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner           FT_READ_ULONG( *offset ) || FT_READ_ULONG( *length ) )
143877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        return error;
143977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
144077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      if ( tag == TTAG_CID )
144177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      {
144277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        pstable_index++;
144377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        *offset += 22;
144477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        *length -= 22;
144577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        *is_sfnt_cid = TRUE;
144677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        if ( face_index < 0 )
144777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          return FT_Err_Ok;
144877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      }
144977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      else if ( tag == TTAG_TYP1 )
145077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      {
145177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        pstable_index++;
145277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        *offset += 24;
145377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        *length -= 24;
145477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        *is_sfnt_cid = FALSE;
145577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        if ( face_index < 0 )
145677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          return FT_Err_Ok;
145777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      }
145877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      if ( face_index >= 0 && pstable_index == face_index )
145977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        return FT_Err_Ok;
146077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    }
146177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    return FT_Err_Table_Missing;
146277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  }
146377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
146477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
146577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  FT_LOCAL_DEF( FT_Error )
146677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  open_face_PS_from_sfnt_stream( FT_Library     library,
146777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                 FT_Stream      stream,
146877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                 FT_Long        face_index,
146977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                 FT_Int         num_params,
147077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                 FT_Parameter  *params,
147177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                 FT_Face       *aface )
147277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  {
147377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Error   error;
147477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Memory  memory = library->memory;
147577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_ULong   offset, length;
147677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Long    pos;
147777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Bool    is_sfnt_cid;
1478aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_Byte*   sfnt_ps = NULL;
147977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
148077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_UNUSED( num_params );
148177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_UNUSED( params );
148277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
148377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
148477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    pos = FT_Stream_Pos( stream );
148577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
148677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    error = ft_lookup_PS_in_sfnt_stream( stream,
148777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                         face_index,
148877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                         &offset,
148977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                         &length,
149077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                         &is_sfnt_cid );
149177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( error )
149277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      goto Exit;
149377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
149477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( FT_Stream_Seek( stream, pos + offset ) )
149577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      goto Exit;
149677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
149777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) )
149877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      goto Exit;
149977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
150077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length );
150177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( error )
150277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      goto Exit;
150377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
150477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    error = open_face_from_buffer( library,
150577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                   sfnt_ps,
150677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                   length,
150777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                   face_index < 0 ? face_index : 0,
150877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                   is_sfnt_cid ? "cid" : "type1",
150977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                   aface );
151077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  Exit:
151177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    {
151277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      FT_Error  error1;
151377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
151477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
151577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      if ( error == FT_Err_Unknown_File_Format )
151677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      {
151777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        error1 = FT_Stream_Seek( stream, pos );
151877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        if ( error1 )
151977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          return error1;
152077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      }
152177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
152277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      return error;
152377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    }
152477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  }
152577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
152677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
152741371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#ifndef FT_MACINTOSH
152877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
1529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The resource header says we've got resource_cnt `POST' (type1) */
1530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* resources in this file.  They all need to be coalesced into    */
1531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* one lump which gets passed on to the type1 driver.             */
1532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Here can be only one PostScript font in a file so face_index   */
1533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* must be 0 (or -1).                                             */
1534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                */
1535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Mac_Read_POST_Resource( FT_Library  library,
1537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Stream   stream,
1538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Long    *offsets,
1539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Long     resource_cnt,
1540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Long     face_index,
1541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Face    *aface )
1542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error  = FT_Err_Cannot_Open_Resource;
1544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = library->memory;
1545aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_Byte*   pfb_data = NULL;
1546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int        i, type, flags;
1547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    len;
1548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    pfb_len, pfb_pos, pfb_lenpos;
1549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    rlen, temp;
1550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face_index == -1 )
1553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face_index = 0;
1554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face_index != 0 )
1555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
1556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Find the length of all the POST resources, concatenated.  Assume */
1558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* worst case (each resource in its own section).                   */
1559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_len = 0;
1560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0; i < resource_cnt; ++i )
1561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Stream_Seek( stream, offsets[i] );
1563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_READ_LONG( temp ) )
1566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pfb_len += temp + 6;
1568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) )
1571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[0] = 0x80;
1574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[1] = 1;            /* Ascii section */
1575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[2] = 0;            /* 4-byte length, fill in later */
1576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[3] = 0;
1577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[4] = 0;
1578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[5] = 0;
1579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_pos     = 6;
1580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_lenpos  = 2;
1581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    len = 0;
1583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    type = 1;
1584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0; i < resource_cnt; ++i )
1585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Stream_Seek( stream, offsets[i] );
1587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit2;
1589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_READ_LONG( rlen ) )
1590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_READ_USHORT( flags ) )
1592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1593aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n",
1594aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                   i, offsets[i], rlen, flags ));
1595aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1596aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* postpone the check of rlen longer than buffer until FT_Stream_Read() */
1597aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( ( flags >> 8 ) == 0 )        /* Comment, should not be loaded */
1598aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        continue;
1599aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1600aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* the flags are part of the resource, so rlen >= 2.  */
1601aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* but some fonts declare rlen = 0 for empty fragment */
1602aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( rlen > 2 )
1603aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        rlen -= 2;
1604aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      else
1605aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        rlen = 0;
1606aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ( flags >> 8 ) == type )
1608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        len += rlen;
1609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
1610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1611aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( pfb_lenpos + 3 > pfb_len + 2 )
1612aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          goto Exit2;
1613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_lenpos    ] = (FT_Byte)( len );
1614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
1615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
1616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 );
1617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ( flags >> 8 ) == 5 )      /* End of font mark */
1619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
1620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1621aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( pfb_pos + 6 > pfb_len + 2 )
1622aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          goto Exit2;
1623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_pos++] = 0x80;
1624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        type = flags >> 8;
1626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        len = rlen;
1627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_pos++] = (FT_Byte)type;
1629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_lenpos          = pfb_pos;
1630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_pos++] = 0;        /* 4-byte length, fill in later */
1631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_pos++] = 0;
1632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_pos++] = 0;
1633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_pos++] = 0;
1634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1636aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      error = FT_Err_Cannot_Open_Resource;
1637aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len )
1638aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        goto Exit2;
1639aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen );
1641aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( error )
1642aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        goto Exit2;
1643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pfb_pos += rlen;
1644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1646aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( pfb_pos + 2 > pfb_len + 2 )
1647aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      goto Exit2;
1648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[pfb_pos++] = 0x80;
1649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[pfb_pos++] = 3;
1650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1651aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( pfb_lenpos + 3 > pfb_len + 2 )
1652aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      goto Exit2;
1653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[pfb_lenpos    ] = (FT_Byte)( len );
1654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
1655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
1656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 );
1657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return open_face_from_buffer( library,
1659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  pfb_data,
1660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  pfb_pos,
1661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  face_index,
1662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  "type1",
1663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  aface );
1664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit2:
1666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( pfb_data );
1667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The resource header says we've got resource_cnt `sfnt'      */
1674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* (TrueType/OpenType) resources in this file.  Look through   */
1675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* them for the one indicated by face_index, load it into mem, */
1676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* pass it on the the truetype driver and return it.           */
1677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                             */
1678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Mac_Read_sfnt_Resource( FT_Library  library,
1680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Stream   stream,
1681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Long    *offsets,
1682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Long     resource_cnt,
1683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Long     face_index,
1684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Face    *aface )
1685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = library->memory;
1687aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_Byte*   sfnt_data = NULL;
1688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
1689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    flag_offset;
1690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    rlen;
1691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int        is_cff;
1692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    face_index_in_resource = 0;
1693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face_index == -1 )
1696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face_index = 0;
1697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face_index >= resource_cnt )
1698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Cannot_Open_Resource;
1699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    flag_offset = offsets[face_index];
1701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_Seek( stream, flag_offset );
1702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_READ_LONG( rlen ) )
1706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( rlen == -1 )
1708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Cannot_Open_Resource;
1709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
171077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    error = open_face_PS_from_sfnt_stream( library,
171177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                           stream,
171277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                           face_index,
171377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                           0, NULL,
171477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                           aface );
171577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( !error )
171677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      goto Exit;
171777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
171877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */
171977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( FT_Stream_Seek( stream, flag_offset + 4 ) )
172077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      goto Exit;
172177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
1722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) )
1723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
1724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen );
1725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
172877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 );
1729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = open_face_from_buffer( library,
1730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   sfnt_data,
1731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   rlen,
1732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   face_index_in_resource,
1733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   is_cff ? "cff" : "truetype",
1734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   aface );
1735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Check for a valid resource fork header, or a valid dfont    */
1742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* header.  In a resource fork the first 16 bytes are repeated */
1743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* at the location specified by bytes 4-7.  In a dfont bytes   */
1744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* 4-7 point to 16 bytes of zeroes instead.                    */
1745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                             */
1746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  IsMacResource( FT_Library  library,
1748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Stream   stream,
1749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Long     resource_offset,
1750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Long     face_index,
1751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Face    *aface )
1752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = library->memory;
1754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
1755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    map_offset, rdara_pos;
1756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    *data_offsets;
1757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    count;
1758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset,
1761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       &map_offset, &rdara_pos );
1762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
1764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Raccess_Get_DataOffsets( library, stream,
1766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                        map_offset, rdara_pos,
176777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                        TTAG_POST,
1768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                        &data_offsets, &count );
1769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
1770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = Mac_Read_POST_Resource( library, stream, data_offsets, count,
1772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      face_index, aface );
1773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( data_offsets );
1774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* POST exists in an LWFN providing a single face */
1775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !error )
1776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        (*aface)->num_faces = 1;
1777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
1778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Raccess_Get_DataOffsets( library, stream,
1781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                        map_offset, rdara_pos,
178277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                        TTAG_sfnt,
1783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                        &data_offsets, &count );
1784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
1785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Long  face_index_internal = face_index % count;
1787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = Mac_Read_sfnt_Resource( library, stream, data_offsets, count,
1790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      face_index_internal, aface );
1791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( data_offsets );
1792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !error )
1793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        (*aface)->num_faces = count;
1794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Check for a valid macbinary header, and if we find one   */
1801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* check that the (flattened) resource fork in it is valid. */
1802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                          */
1803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  IsMacBinary( FT_Library  library,
1805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Stream   stream,
1806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Long     face_index,
1807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Face    *aface )
1808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned char  header[128];
1810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error       error;
1811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long        dlen, offset;
1812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( NULL == stream )
1815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Stream_Operation;
1816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_Seek( stream, 0 );
1818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_Read( stream, (FT_Byte*)header, 128 );
1822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (            header[ 0] !=  0 ||
1826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    header[74] !=  0 ||
1827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    header[82] !=  0 ||
1828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    header[ 1] ==  0 ||
1829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    header[ 1] >  33 ||
1830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    header[63] !=  0 ||
1831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         header[2 + header[1]] !=  0 )
1832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Unknown_File_Format;
1833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    dlen = ( header[0x53] << 24 ) |
1835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           ( header[0x54] << 16 ) |
1836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           ( header[0x55] <<  8 ) |
1837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             header[0x56];
1838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 0
1839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    rlen = ( header[0x57] << 24 ) |
1840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           ( header[0x58] << 16 ) |
1841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           ( header[0x59] <<  8 ) |
1842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             header[0x5a];
1843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* 0 */
1844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    offset = 128 + ( ( dlen + 127 ) & ~127 );
1845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return IsMacResource( library, stream, offset, face_index, aface );
1847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  load_face_in_embedded_rfork( FT_Library           library,
1855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_Stream            stream,
1856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_Long              face_index,
1857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_Face             *aface,
1858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               const FT_Open_Args  *args )
1859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
1862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_raccess
1863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = library->memory;
1865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error  = FT_Err_Unknown_File_Format;
1866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int        i;
1867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    char *     file_names[FT_RACCESS_N_RULES];
1869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    offsets[FT_RACCESS_N_RULES];
1870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   errors[FT_RACCESS_N_RULES];
18717f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    FT_Bool    is_darwin_vfs, vfs_rfork_has_no_font = FALSE; /* not tested */
1872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Open_Args  args2;
187477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Stream     stream2 = 0;
1875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Raccess_Guess( library, stream,
1878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      args->pathname, file_names, offsets, errors );
1879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
1881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
188241371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      is_darwin_vfs = ft_raccess_rule_by_darwin_vfs( library, i );
18837f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      if ( is_darwin_vfs && vfs_rfork_has_no_font )
18847f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      {
18857f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        FT_TRACE3(( "Skip rule %d: darwin vfs resource fork"
18867f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner                    " is already checked and"
18877f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner                    " no font is found\n", i ));
18887f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        continue;
1889aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      }
18907f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
1891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( errors[i] )
1892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i ));
1894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        continue;
1895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      args2.flags    = FT_OPEN_PATHNAME;
1898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      args2.pathname = file_names[i] ? file_names[i] : args->pathname;
1899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_TRACE3(( "Try rule %d: %s (offset=%d) ...",
1901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  i, args2.pathname, offsets[i] ));
1902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Stream_New( library, &args2, &stream2 );
19047f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      if ( is_darwin_vfs && error == FT_Err_Cannot_Open_Stream )
19057f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        vfs_rfork_has_no_font = TRUE;
19067f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
1907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_TRACE3(( "failed\n" ));
1910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        continue;
1911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = IsMacResource( library, stream2, offsets[i],
1914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             face_index, aface );
1915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_Free( stream2, 0 );
1916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_TRACE3(( "%s\n", error ? "failed": "successful" ));
1918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !error )
1920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
19217f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      else if ( is_darwin_vfs )
19227f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner          vfs_rfork_has_no_font = TRUE;
1923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for (i = 0; i < FT_RACCESS_N_RULES; i++)
1926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( file_names[i] )
1928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FREE( file_names[i] );
1929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Caller (load_mac_face) requires FT_Err_Unknown_File_Format. */
1932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Err_Unknown_File_Format;
1934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
1938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_objs
1939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
194377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* Check for some macintosh formats without Carbon framework.    */
1944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Is this a macbinary file?  If so look at the resource fork.   */
1945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Is this a mac dfont file?                                     */
1946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Is this an old style resource fork? (in data)                 */
1947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Else call load_face_in_embedded_rfork to try extra rules      */
1948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* (defined in `ftrfork.c').                                     */
1949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                               */
1950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  load_mac_face( FT_Library           library,
1952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Stream            stream,
1953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Long              face_index,
1954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Face             *aface,
1955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const FT_Open_Args  *args )
1956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error error;
1958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( args );
1959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = IsMacBinary( library, stream, face_index, aface );
1962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format )
1963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
1966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_raccess
1967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_TRACE3(( "Try as dfont: %s ...", args->pathname ));
1969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = IsMacResource( library, stream, 0, face_index, aface );
1971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_TRACE3(( "%s\n", error ? "failed" : "successful" ));
1973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
1975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_objs
1976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ( FT_ERROR_BASE( error ) == FT_Err_Unknown_File_Format      ||
1980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           FT_ERROR_BASE( error ) == FT_Err_Invalid_Stream_Operation ) &&
1981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         ( args->flags & FT_OPEN_PATHNAME )                            )
1982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = load_face_in_embedded_rfork( library, stream,
1983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           face_index, aface, args );
1984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
198677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#endif
1987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif  /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */
1989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
1992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
1994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Open_Face( FT_Library           library,
1995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                const FT_Open_Args*  args,
1996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Long              face_index,
1997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Face             *aface )
1998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error;
2000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver    driver;
2001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory    memory;
2002aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Stream    stream = NULL;
2003aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Face      face   = NULL;
2004aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_ListNode  node   = NULL;
2005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bool      external_stream;
2006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module*   cur;
2007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module*   limit;
2008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `library' delayed to */
2011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* FT_Stream_New()                     */
2012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ( !aface && face_index >= 0 ) || !args )
2014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Argument;
2015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) &&
2017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               args->stream                     );
2018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* create input stream */
2020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_New( library, args, &stream );
2021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
2022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail3;
2023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = library->memory;
2025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* If the font driver is specified in the `args' structure, use */
2027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* it.  Otherwise, we scan the list of registered drivers.      */
2028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ( args->flags & FT_OPEN_DRIVER ) && args->driver )
2029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      driver = FT_DRIVER( args->driver );
2031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* not all modules are drivers, so check... */
2033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_MODULE_IS_DRIVER( driver ) )
2034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int         num_params = 0;
2036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Parameter*  params     = 0;
2037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( args->flags & FT_OPEN_PARAMS )
2040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
2041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          num_params = args->num_params;
2042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          params     = args->params;
2043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
2044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = open_face( driver, stream, face_index,
2046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           num_params, params, &face );
2047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !error )
2048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Success;
2049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
2051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = FT_Err_Invalid_Handle;
2052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_Free( stream, external_stream );
2054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
2055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
2057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* check each font driver for an appropriate format */
2059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur   = library->modules;
2060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      limit = cur + library->num_modules;
2061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; cur < limit; cur++ )
2064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* not all modules are font drivers, so check... */
2066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_MODULE_IS_DRIVER( cur[0] ) )
2067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
2068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Int         num_params = 0;
2069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Parameter*  params     = 0;
2070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          driver = FT_DRIVER( cur[0] );
2073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( args->flags & FT_OPEN_PARAMS )
2075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
2076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            num_params = args->num_params;
2077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            params     = args->params;
2078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
2079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          error = open_face( driver, stream, face_index,
2081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             num_params, params, &face );
2082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( !error )
2083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Success;
2084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
208577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#ifdef FT_CONFIG_OPTION_MAC_FONTS
208677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 &&
208777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner               FT_ERROR_BASE( error ) == FT_Err_Table_Missing           )
208877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          {
208977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            /* TrueType but essential tables are missing */
209077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            if ( FT_Stream_Seek( stream, 0 ) )
209177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner              break;
209277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
209377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            error = open_face_PS_from_sfnt_stream( library,
209477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                                   stream,
209577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                                   face_index,
209677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                                   num_params,
209777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                                   params,
209877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                                   aface );
209977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            if ( !error )
210077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            {
210177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner              FT_Stream_Free( stream, external_stream );
210277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner              return error;
210377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            }
210477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          }
210577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#endif
210677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
2107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format )
2108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Fail3;
2109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
2110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail3:
2113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* If we are on the mac, and we get an FT_Err_Invalid_Stream_Operation */
2114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* it may be because we have an empty data fork, so we need to check   */
2115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the resource fork.                                                  */
2116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ERROR_BASE( error ) != FT_Err_Cannot_Open_Stream       &&
2117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format      &&
2118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_ERROR_BASE( error ) != FT_Err_Invalid_Stream_Operation )
2119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail2;
2120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS )
2122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = load_mac_face( library, stream, face_index, aface, args );
2123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
2124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* We don't want to go to Success here.  We've already done that. */
2126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* On the other hand, if we succeeded we still need to close this */
2127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* stream (we opened a different stream which extracted the       */
2128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* interesting information out of this stream here.  That stream  */
2129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* will still be open and the face will point to it).             */
2130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_Free( stream, external_stream );
2131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
2132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ERROR_BASE( error ) != FT_Err_Unknown_File_Format )
2135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail2;
2136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif  /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */
2137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* no driver is able to handle this format */
2139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Err_Unknown_File_Format;
2140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail2:
2142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_Free( stream, external_stream );
2143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
2144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Success:
2147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" ));
2148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */
2150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( external_stream )
2151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;
2152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* add the face object to its driver's list */
2154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( node ) )
2155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
2156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node->data = face;
2158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* don't assume driver is the same as face->driver, so use */
2159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* face->driver instead.                                   */
2160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_List_Add( &face->driver->faces_list, node );
2161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* now allocate a glyph slot object for the face */
2163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" ));
2164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face_index >= 0 )
2166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_New_GlyphSlot( face, NULL );
2168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
2169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
2170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* finally, allocate a size object for the face */
2172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Size  size;
2174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_TRACE4(( "FT_Open_Face: Creating size object\n" ));
2177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = FT_New_Size( face, &size );
2179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
2180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
2181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->size = size;
2183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* some checks */
2187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_IS_SCALABLE( face ) )
2189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( face->height < 0 )
2191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->height = (FT_Short)-face->height;
2192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !FT_HAS_VERTICAL( face ) )
2194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->max_advance_height = (FT_Short)face->height;
2195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_HAS_FIXED_SIZES( face ) )
2198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int  i;
2200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( i = 0; i < face->num_fixed_sizes; i++ )
2203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Bitmap_Size*  bsize = face->available_sizes + i;
2205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( bsize->height < 0 )
2208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          bsize->height = (FT_Short)-bsize->height;
2209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( bsize->x_ppem < 0 )
2210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          bsize->x_ppem = (FT_Short)-bsize->x_ppem;
2211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( bsize->y_ppem < 0 )
2212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          bsize->y_ppem = -bsize->y_ppem;
2213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* initialize internal face data */
2217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Face_Internal  internal = face->internal;
2219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.xx = 0x10000L;
2222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.xy = 0;
2223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.yx = 0;
2224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.yy = 0x10000L;
2225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_delta.x = 0;
2227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_delta.y = 0;
2228aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2229aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      internal->refcount = 1;
2230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( aface )
2233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *aface = face;
2234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
2235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Done_Face( face );
2236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
2238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
2240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Done_Face( face );
2241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
2243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE4(( "FT_Open_Face: Return %d\n", error ));
2244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Attach_File( FT_Face      face,
2253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  const char*  filepathname )
2254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Open_Args  open;
2256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `face' delayed to FT_Attach_Stream() */
2259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !filepathname )
2261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Argument;
2262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    open.stream   = NULL;
2264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    open.flags    = FT_OPEN_PATHNAME;
2265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    open.pathname = (char*)filepathname;
2266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Attach_Stream( face, &open );
2268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Attach_Stream( FT_Face        face,
2275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Open_Args*  parameters )
2276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream  stream;
2278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
2279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver  driver;
2280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz;
2282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `parameters' delayed to FT_Stream_New() */
2285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
2287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Face_Handle;
2288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    driver = face->driver;
2290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !driver )
2291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Driver_Handle;
2292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_New( driver->root.library, parameters, &stream );
2294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
2295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
2296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* we implement FT_Attach_Stream in each driver through the */
2298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* `attach_file' interface                                  */
2299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Err_Unimplemented_Feature;
2301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clazz = driver->clazz;
2302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->attach_file )
2303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = clazz->attach_file( face, stream );
2304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* close the attached stream */
2306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream_Free( stream,
2307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    (FT_Bool)( parameters->stream &&
2308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               ( parameters->flags & FT_OPEN_STREAM ) ) );
2309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
2311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2318aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  FT_Reference_Face( FT_Face  face )
2319aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  {
2320aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    face->internal->refcount++;
2321aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2322aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    return FT_Err_Ok;
2323aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  }
2324aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2325aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2326aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  /* documentation is in freetype.h */
2327aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2328aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  FT_EXPORT_DEF( FT_Error )
2329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Done_Face( FT_Face  face )
2330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error;
2332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver    driver;
2333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory    memory;
2334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ListNode  node;
2335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Err_Invalid_Face_Handle;
2338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face && face->driver )
2339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2340aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      face->internal->refcount--;
2341aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( face->internal->refcount > 0 )
2342aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        error = FT_Err_Ok;
2343aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      else
2344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2345aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        driver = face->driver;
2346aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        memory = driver->root.memory;
2347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2348aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        /* find face in driver's list */
2349aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        node = FT_List_Find( &driver->faces_list, face );
2350aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( node )
2351aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
2352aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          /* remove face object from the driver's list */
2353aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_List_Remove( &driver->faces_list, node );
2354aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_FREE( node );
2355aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2356aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          /* now destroy the object proper */
2357aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          destroy_face( memory, face, driver );
2358aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          error = FT_Err_Ok;
2359aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        }
2360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2362aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
2368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_New_Size( FT_Face   face,
2371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Size  *asize )
2372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error         error;
2374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory        memory;
2375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver        driver;
2376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz;
2377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Size          size = 0;
2379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ListNode      node = 0;
2380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
2383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Face_Handle;
2384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !asize )
2386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Size_Handle;
2387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face->driver )
2389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Driver_Handle;
2390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *asize = 0;
2392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    driver = face->driver;
2394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clazz  = driver->clazz;
2395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = face->memory;
2396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Allocate new size object and perform basic initialisation */
2398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( size, clazz->size_object_size ) || FT_NEW( node ) )
2399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
2400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    size->face = face;
2402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* for now, do not use any internal fields in size objects */
2404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    size->internal = 0;
2405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->init_size )
2407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = clazz->init_size( size );
2408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* in case of success, add to the face's list */
2410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
2411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *asize     = size;
2413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      node->data = size;
2414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_List_Add( &face->sizes_list, node );
2415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
2418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
2419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( node );
2421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( size );
2422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
2429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Done_Size( FT_Size  size )
2432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error;
2434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver    driver;
2435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory    memory;
2436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face      face;
2437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ListNode  node;
2438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !size )
2441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Size_Handle;
2442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face = size->face;
2444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
2445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Face_Handle;
2446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    driver = face->driver;
2448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !driver )
2449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Driver_Handle;
2450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = driver->root.memory;
2452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Err_Ok;
2454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node  = FT_List_Find( &face->sizes_list, size );
2455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( node )
2456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_List_Remove( &face->sizes_list, node );
2458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( node );
2459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( face->size == size )
2461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->size = 0;
2463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( face->sizes_list.head )
2464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          face->size = (FT_Size)(face->sizes_list.head->data);
2465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      destroy_size( memory, size, driver );
2468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
2470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Err_Invalid_Size_Handle;
2471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
2477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
2479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Match_Size( FT_Face          face,
2480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Size_Request  req,
2481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Bool          ignore_width,
2482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_ULong*        size_index )
2483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int   i;
2485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long  w, h;
2486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_HAS_FIXED_SIZES( face ) )
2489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Face_Handle;
2490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* FT_Bitmap_Size doesn't provide enough info... */
2492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )
2493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Unimplemented_Feature;
2494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    w = FT_REQUEST_WIDTH ( req );
2496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    h = FT_REQUEST_HEIGHT( req );
2497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( req->width && !req->height )
2499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      h = w;
2500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( !req->width && req->height )
2501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      w = h;
2502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    w = FT_PIX_ROUND( w );
2504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    h = FT_PIX_ROUND( h );
2505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0; i < face->num_fixed_sizes; i++ )
2507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Bitmap_Size*  bsize = face->available_sizes + i;
2509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( h != FT_PIX_ROUND( bsize->y_ppem ) )
2512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        continue;
2513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( w == FT_PIX_ROUND( bsize->x_ppem ) || ignore_width )
2515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( size_index )
2517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *size_index = (FT_ULong)i;
2518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return FT_Err_Ok;
2520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Invalid_Pixel_Size;
2524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
2528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
2530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_synthesize_vertical_metrics( FT_Glyph_Metrics*  metrics,
2531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  FT_Pos             advance )
2532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2533295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_Pos  height = metrics->height;
2534295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
2535295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
2536295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* compensate for glyph with bbox above/below the baseline */
2537295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( metrics->horiBearingY < 0 )
2538295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    {
2539295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      if ( height < metrics->horiBearingY )
2540295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        height = metrics->horiBearingY;
2541295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    }
2542295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    else if ( metrics->horiBearingY > 0 )
2543295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      height -= metrics->horiBearingY;
2544295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
2545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the factor 1.2 is a heuristical value */
2546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !advance )
2547295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      advance = height * 12 / 10;
2548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2549295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    metrics->vertBearingX = metrics->horiBearingX - metrics->horiAdvance / 2;
2550295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    metrics->vertBearingY = ( advance - height ) / 2;
2551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->vertAdvance  = advance;
2552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
2556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_recompute_scaled_metrics( FT_Face           face,
2557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_Size_Metrics*  metrics )
2558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Compute root ascender, descender, test height, and max_advance */
2560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef GRID_FIT_METRICS
2562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->ascender    = FT_PIX_CEIL( FT_MulFix( face->ascender,
2563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                   metrics->y_scale ) );
2564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->descender   = FT_PIX_FLOOR( FT_MulFix( face->descender,
2566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                    metrics->y_scale ) );
2567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->height      = FT_PIX_ROUND( FT_MulFix( face->height,
2569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                    metrics->y_scale ) );
2570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->max_advance = FT_PIX_ROUND( FT_MulFix( face->max_advance_width,
2572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                    metrics->x_scale ) );
2573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !GRID_FIT_METRICS */
2574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->ascender    = FT_MulFix( face->ascender,
2575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      metrics->y_scale );
2576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->descender   = FT_MulFix( face->descender,
2578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      metrics->y_scale );
2579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->height      = FT_MulFix( face->height,
2581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      metrics->y_scale );
2582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->max_advance = FT_MulFix( face->max_advance_width,
2584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      metrics->x_scale );
2585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* !GRID_FIT_METRICS */
2586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
2590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Select_Metrics( FT_Face   face,
2591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_ULong  strike_index )
2592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Size_Metrics*  metrics;
2594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bitmap_Size*   bsize;
2595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics = &face->size->metrics;
2598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bsize   = face->available_sizes + strike_index;
2599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->x_ppem = (FT_UShort)( ( bsize->x_ppem + 32 ) >> 6 );
2601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->y_ppem = (FT_UShort)( ( bsize->y_ppem + 32 ) >> 6 );
2602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_IS_SCALABLE( face ) )
2604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->x_scale = FT_DivFix( bsize->x_ppem,
2606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                    face->units_per_EM );
2607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->y_scale = FT_DivFix( bsize->y_ppem,
2608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                    face->units_per_EM );
2609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_recompute_scaled_metrics( face, metrics );
2611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
2613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
261477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      metrics->x_scale     = 1L << 16;
261577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      metrics->y_scale     = 1L << 16;
2616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->ascender    = bsize->y_ppem;
2617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->descender   = 0;
2618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->height      = bsize->height << 6;
2619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->max_advance = bsize->x_ppem;
2620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2621bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2622bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "FT_Select_Metrics:\n" ));
2623bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  x scale: %d (%f)\n",
2624bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                metrics->x_scale, metrics->x_scale / 65536.0 ));
2625bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  y scale: %d (%f)\n",
2626bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                metrics->y_scale, metrics->y_scale / 65536.0 ));
2627bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  ascender: %f\n",    metrics->ascender / 64.0 ));
2628bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  descender: %f\n",   metrics->descender / 64.0 ));
2629bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  height: %f\n",      metrics->height / 64.0 ));
2630bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  max advance: %f\n", metrics->max_advance / 64.0 ));
2631bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  x ppem: %d\n",      metrics->x_ppem ));
2632bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  y ppem: %d\n",      metrics->y_ppem ));
2633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
2637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Request_Metrics( FT_Face          face,
2638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Size_Request  req )
2639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Size_Metrics*  metrics;
2641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics = &face->size->metrics;
2644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_IS_SCALABLE( face ) )
2646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Long  w = 0, h = 0, scaled_w = 0, scaled_h = 0;
2648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( req->type )
2651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case FT_SIZE_REQUEST_TYPE_NOMINAL:
2653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        w = h = face->units_per_EM;
2654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
2655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case FT_SIZE_REQUEST_TYPE_REAL_DIM:
2657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        w = h = face->ascender - face->descender;
2658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
2659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case FT_SIZE_REQUEST_TYPE_BBOX:
2661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        w = face->bbox.xMax - face->bbox.xMin;
2662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        h = face->bbox.yMax - face->bbox.yMin;
2663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
2664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case FT_SIZE_REQUEST_TYPE_CELL:
2666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        w = face->max_advance_width;
2667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        h = face->ascender - face->descender;
2668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
2669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case FT_SIZE_REQUEST_TYPE_SCALES:
2671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->x_scale = (FT_Fixed)req->width;
2672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->y_scale = (FT_Fixed)req->height;
2673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !metrics->x_scale )
2674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          metrics->x_scale = metrics->y_scale;
2675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else if ( !metrics->y_scale )
2676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          metrics->y_scale = metrics->x_scale;
2677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Calculate_Ppem;
2678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case FT_SIZE_REQUEST_TYPE_MAX:
2680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
2681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* to be on the safe side */
2684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( w < 0 )
2685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        w = -w;
2686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( h < 0 )
2688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        h = -h;
2689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      scaled_w = FT_REQUEST_WIDTH ( req );
2691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      scaled_h = FT_REQUEST_HEIGHT( req );
2692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* determine scales */
2694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( req->width )
2695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->x_scale = FT_DivFix( scaled_w, w );
2697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( req->height )
2699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
2700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          metrics->y_scale = FT_DivFix( scaled_h, h );
2701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( req->type == FT_SIZE_REQUEST_TYPE_CELL )
2703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
2704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( metrics->y_scale > metrics->x_scale )
2705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              metrics->y_scale = metrics->x_scale;
2706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            else
2707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              metrics->x_scale = metrics->y_scale;
2708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
2709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
2710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
2711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
2712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          metrics->y_scale = metrics->x_scale;
2713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          scaled_h = FT_MulDiv( scaled_w, h, w );
2714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
2715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
2717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->x_scale = metrics->y_scale = FT_DivFix( scaled_h, h );
2719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        scaled_w = FT_MulDiv( scaled_h, w, h );
2720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Calculate_Ppem:
2723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* calculate the ppems */
2724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )
2725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        scaled_w = FT_MulFix( face->units_per_EM, metrics->x_scale );
2727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        scaled_h = FT_MulFix( face->units_per_EM, metrics->y_scale );
2728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->x_ppem = (FT_UShort)( ( scaled_w + 32 ) >> 6 );
2731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->y_ppem = (FT_UShort)( ( scaled_h + 32 ) >> 6 );
2732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_recompute_scaled_metrics( face, metrics );
2734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
2736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ZERO( metrics );
273877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      metrics->x_scale = 1L << 16;
273977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      metrics->y_scale = 1L << 16;
2740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2741bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2742bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "FT_Request_Metrics:\n" ));
2743bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  x scale: %d (%f)\n",
2744bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                metrics->x_scale, metrics->x_scale / 65536.0 ));
2745bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  y scale: %d (%f)\n",
2746bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                metrics->y_scale, metrics->y_scale / 65536.0 ));
2747bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  ascender: %f\n",    metrics->ascender / 64.0 ));
2748bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  descender: %f\n",   metrics->descender / 64.0 ));
2749bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  height: %f\n",      metrics->height / 64.0 ));
2750bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  max advance: %f\n", metrics->max_advance / 64.0 ));
2751bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  x ppem: %d\n",      metrics->x_ppem ));
2752bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  y ppem: %d\n",      metrics->y_ppem ));
2753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Select_Size( FT_Face  face,
2760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Int   strike_index )
2761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz;
2763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face || !FT_HAS_FIXED_SIZES( face ) )
2766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Face_Handle;
2767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( strike_index < 0 || strike_index >= face->num_fixed_sizes )
2769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Argument;
2770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clazz = face->driver->clazz;
2772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->select_size )
2774bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
2775bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_Error  error;
2776bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2777bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2778bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      error = clazz->select_size( face->size, (FT_ULong)strike_index );
2779bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2780bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#ifdef FT_DEBUG_LEVEL_TRACE
2781bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      {
2782bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_Size_Metrics*  metrics = &face->size->metrics;
2783bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2784bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2785bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "FT_Select_Size (font driver's `select_size'):\n" ));
2786bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  x scale: %d (%f)\n",
2787bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                    metrics->x_scale, metrics->x_scale / 65536.0 ));
2788bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  y scale: %d (%f)\n",
2789bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                    metrics->y_scale, metrics->y_scale / 65536.0 ));
2790bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  ascender: %f\n",    metrics->ascender / 64.0 ));
2791bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  descender: %f\n",   metrics->descender / 64.0 ));
2792bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  height: %f\n",      metrics->height / 64.0 ));
2793bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  max advance: %f\n", metrics->max_advance / 64.0 ));
2794bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  x ppem: %d\n",      metrics->x_ppem ));
2795bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  y ppem: %d\n",      metrics->y_ppem ));
2796bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      }
2797bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#endif
2798bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2799bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      return error;
2800bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
2801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Select_Metrics( face, (FT_ULong)strike_index );
2803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Ok;
2805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Request_Size( FT_Face          face,
2812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Size_Request  req )
2813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz;
2815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong         strike_index;
2816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
2819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Face_Handle;
2820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !req || req->width < 0 || req->height < 0 ||
2822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         req->type >= FT_SIZE_REQUEST_TYPE_MAX )
2823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Argument;
2824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clazz = face->driver->clazz;
2826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->request_size )
2828bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
2829bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_Error  error;
2830bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2831bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2832bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      error = clazz->request_size( face->size, req );
2833bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2834bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#ifdef FT_DEBUG_LEVEL_TRACE
2835bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      {
2836bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_Size_Metrics*  metrics = &face->size->metrics;
2837bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2838bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2839bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "FT_Request_Size (font driver's `request_size'):\n" ));
2840bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  x scale: %d (%f)\n",
2841bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                    metrics->x_scale, metrics->x_scale / 65536.0 ));
2842bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  y scale: %d (%f)\n",
2843bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                    metrics->y_scale, metrics->y_scale / 65536.0 ));
2844bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  ascender: %f\n",    metrics->ascender / 64.0 ));
2845bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  descender: %f\n",   metrics->descender / 64.0 ));
2846bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  height: %f\n",      metrics->height / 64.0 ));
2847bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  max advance: %f\n", metrics->max_advance / 64.0 ));
2848bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  x ppem: %d\n",      metrics->x_ppem ));
2849bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  y ppem: %d\n",      metrics->y_ppem ));
2850bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      }
2851bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#endif
2852bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2853bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      return error;
2854bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
2855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*
2857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * The reason that a driver doesn't have `request_size' defined is
2858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * either that the scaling here suffices or that the supported formats
2859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * are bitmap-only and size matching is not implemented.
2860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
2861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * In the latter case, a simple size matching is done.
2862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     */
2863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_IS_SCALABLE( face ) && FT_HAS_FIXED_SIZES( face ) )
2864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Error  error;
2866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Match_Size( face, req, 0, &strike_index );
2869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
2870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return error;
2871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_TRACE3(( "FT_Request_Size: bitmap strike %lu matched\n",
2873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  strike_index ));
2874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Select_Size( face, (FT_Int)strike_index );
2876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Request_Metrics( face, req );
2879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Ok;
2881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Set_Char_Size( FT_Face     face,
2888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_F26Dot6  char_width,
2889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_F26Dot6  char_height,
2890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_UInt     horz_resolution,
2891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_UInt     vert_resolution )
2892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Size_RequestRec  req;
2894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !char_width )
2897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      char_width = char_height;
2898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( !char_height )
2899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      char_height = char_width;
2900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !horz_resolution )
2902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      horz_resolution = vert_resolution;
2903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( !vert_resolution )
2904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vert_resolution = horz_resolution;
2905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( char_width  < 1 * 64 )
2907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      char_width  = 1 * 64;
2908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( char_height < 1 * 64 )
2909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      char_height = 1 * 64;
2910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !horz_resolution )
2912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      horz_resolution = vert_resolution = 72;
2913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.type           = FT_SIZE_REQUEST_TYPE_NOMINAL;
2915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.width          = char_width;
2916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.height         = char_height;
2917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.horiResolution = horz_resolution;
2918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.vertResolution = vert_resolution;
2919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Request_Size( face, &req );
2921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Set_Pixel_Sizes( FT_Face  face,
2928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_UInt  pixel_width,
2929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_UInt  pixel_height )
2930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Size_RequestRec  req;
2932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pixel_width == 0 )
2935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pixel_width = pixel_height;
2936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( pixel_height == 0 )
2937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pixel_height = pixel_width;
2938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pixel_width  < 1 )
2940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pixel_width  = 1;
2941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pixel_height < 1 )
2942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pixel_height = 1;
2943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* use `>=' to avoid potential compiler warning on 16bit platforms */
2945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pixel_width  >= 0xFFFFU )
2946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pixel_width  = 0xFFFFU;
2947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pixel_height >= 0xFFFFU )
2948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pixel_height = 0xFFFFU;
2949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.type           = FT_SIZE_REQUEST_TYPE_NOMINAL;
2951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.width          = pixel_width << 6;
2952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.height         = pixel_height << 6;
2953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.horiResolution = 0;
2954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.vertResolution = 0;
2955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Request_Size( face, &req );
2957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Kerning( FT_Face     face,
2964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_UInt     left_glyph,
2965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_UInt     right_glyph,
2966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_UInt     kern_mode,
2967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Vector  *akerning )
2968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error = FT_Err_Ok;
2970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver  driver;
2971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
2974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Face_Handle;
2975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !akerning )
2977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Argument;
2978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    driver = face->driver;
2980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    akerning->x = 0;
2982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    akerning->y = 0;
2983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( driver->clazz->get_kerning )
2985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = driver->clazz->get_kerning( face,
2987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                          left_glyph,
2988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                          right_glyph,
2989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                          akerning );
2990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !error )
2991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( kern_mode != FT_KERNING_UNSCALED )
2993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
2994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          akerning->x = FT_MulFix( akerning->x, face->size->metrics.x_scale );
2995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          akerning->y = FT_MulFix( akerning->y, face->size->metrics.y_scale );
2996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( kern_mode != FT_KERNING_UNFITTED )
2998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
2999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* we scale down kerning values for small ppem values */
3000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* to avoid that rounding makes them too big.         */
3001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* `25' has been determined heuristically.            */
3002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( face->size->metrics.x_ppem < 25 )
3003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              akerning->x = FT_MulDiv( akerning->x,
3004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       face->size->metrics.x_ppem, 25 );
3005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( face->size->metrics.y_ppem < 25 )
3006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              akerning->y = FT_MulDiv( akerning->y,
3007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       face->size->metrics.y_ppem, 25 );
3008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            akerning->x = FT_PIX_ROUND( akerning->x );
3010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            akerning->y = FT_PIX_ROUND( akerning->y );
3011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
3012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
3013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
3017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Track_Kerning( FT_Face    face,
3024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Fixed   point_size,
3025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Int     degree,
3026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Fixed*  akerning )
3027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Service_Kerning  service;
3029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error            error = FT_Err_Ok;
3030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
3033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Face_Handle;
3034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !akerning )
3036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Argument;
3037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FACE_FIND_SERVICE( face, service, KERNING );
3039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !service )
3040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Unimplemented_Feature;
3041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = service->get_track( face,
3043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                point_size,
3044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                degree,
3045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                akerning );
3046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
3048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Select_Charmap( FT_Face      face,
3055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Encoding  encoding )
3056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  cur;
3058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  limit;
3059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
3062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Face_Handle;
3063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( encoding == FT_ENCODING_NONE )
3065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Argument;
3066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* FT_ENCODING_UNICODE is special.  We try to find the `best' Unicode */
3068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* charmap available, i.e., one with UCS-4 characters, if possible.   */
3069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                    */
3070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* This is done by find_unicode_charmap() above, to share code.       */
3071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( encoding == FT_ENCODING_UNICODE )
3072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return find_unicode_charmap( face );
3073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur = face->charmaps;
3075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !cur )
3076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_CharMap_Handle;
3077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    limit = cur + face->num_charmaps;
3079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; cur < limit; cur++ )
3081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur[0]->encoding == encoding )
3083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3084aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE
3085aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE )
3086aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
3087aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_ERROR(( "FT_Select_Charmap: requested charmap is found (%d), "
3088aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                     "but in too late position to cache\n",
3089aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                     cur - face->charmaps ));
3090aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          continue;
3091aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        }
3092aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
3093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->charmap = cur[0];
3094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return 0;
3095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Invalid_Argument;
3099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Set_Charmap( FT_Face     face,
3106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_CharMap  charmap )
3107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  cur;
3109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  limit;
3110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
3113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Face_Handle;
3114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur = face->charmaps;
3116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !cur )
3117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_CharMap_Handle;
3118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_Get_CMap_Format( charmap ) == 14 )
3119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Argument;
3120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    limit = cur + face->num_charmaps;
3122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; cur < limit; cur++ )
3124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur[0] == charmap )
3126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3127aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE
3128aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE )
3129aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
3130aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_ERROR(( "FT_Set_Charmap: requested charmap is found (%d), "
3131aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                     "but in too late position to cache\n",
3132aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                     cur - face->charmaps ));
3133aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          continue;
3134aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        }
3135aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
3136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->charmap = cur[0];
3137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return 0;
3138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Invalid_Argument;
3141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Int )
3147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Charmap_Index( FT_CharMap  charmap )
3148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int  i;
3150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3152aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( !charmap || !charmap->face )
3153aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      return -1;
3154aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
3155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0; i < charmap->face->num_charmaps; i++ )
3156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charmap->face->charmaps[i] == charmap )
3157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
3158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( i < charmap->face->num_charmaps );
3160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3161aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE
3162aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( i > FT_MAX_CHARMAP_CACHEABLE )
3163aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    {
3164aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_ERROR(( "FT_Get_Charmap_Index: requested charmap is found (%d), "
3165aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                 "but in too late position to cache\n",
3166aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                 i ));
3167aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      return -i;
3168aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    }
3169aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
3170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return i;
3171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
3175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_cmap_done_internal( FT_CMap  cmap )
3176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CMap_Class  clazz  = cmap->clazz;
3178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face        face   = cmap->charmap.face;
3179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory      memory = FT_FACE_MEMORY(face);
3180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->done )
3183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      clazz->done( cmap );
3184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( cmap );
3186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
3190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_CMap_Done( FT_CMap  cmap )
3191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( cmap )
3193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Face    face   = cmap->charmap.face;
3195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Memory  memory = FT_FACE_MEMORY( face );
3196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Error   error;
3197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int     i, j;
3198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( i = 0; i < face->num_charmaps; i++ )
3201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( (FT_CMap)face->charmaps[i] == cmap )
3203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
3204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_CharMap  last_charmap = face->charmaps[face->num_charmaps - 1];
3205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( FT_RENEW_ARRAY( face->charmaps,
3208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               face->num_charmaps,
3209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               face->num_charmaps - 1 ) )
3210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            return;
3211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* remove it from our list of charmaps */
3213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( j = i + 1; j < face->num_charmaps; j++ )
3214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
3215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( j == face->num_charmaps - 1 )
3216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              face->charmaps[j - 1] = last_charmap;
3217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            else
3218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              face->charmaps[j - 1] = face->charmaps[j];
3219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
3220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          face->num_charmaps--;
3222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( (FT_CMap)face->charmap == cmap )
3224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            face->charmap = NULL;
3225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ft_cmap_done_internal( cmap );
3227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
3229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
3230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
3236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_CMap_New( FT_CMap_Class  clazz,
3237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Pointer     init_data,
3238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_CharMap     charmap,
3239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_CMap       *acmap )
3240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error = FT_Err_Ok;
3242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face    face;
3243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory;
3244aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_CMap    cmap = NULL;
3245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz == NULL || charmap == NULL || charmap->face == NULL )
3248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Argument;
3249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face   = charmap->face;
3251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = FT_FACE_MEMORY( face );
3252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_ALLOC( cmap, clazz->size ) )
3254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cmap->charmap = *charmap;
3256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cmap->clazz   = clazz;
3257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( clazz->init )
3259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = clazz->init( cmap, init_data );
3261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
3262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
3263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* add it to our list of charmaps */
3266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_RENEW_ARRAY( face->charmaps,
3267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           face->num_charmaps,
3268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           face->num_charmaps + 1 ) )
3269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
3270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->charmaps[face->num_charmaps++] = (FT_CharMap)cmap;
3272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
3275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( acmap )
3276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *acmap = cmap;
3277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
3279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
3281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_cmap_done_internal( cmap );
3282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cmap = NULL;
3283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
3284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_UInt )
3290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Char_Index( FT_Face   face,
3291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_ULong  charcode )
3292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  result = 0;
3294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face && face->charmap )
3297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CMap  cmap = FT_CMAP( face->charmap );
3299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3301295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      if ( charcode > 0xFFFFFFFFUL )
3302295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      {
3303295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
3304295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3305295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      }
3306295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode );
3307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3308aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    return result;
3309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_ULong )
3315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_First_Char( FT_Face   face,
3316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_UInt  *agindex )
3317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong  result = 0;
3319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt   gindex = 0;
3320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3322aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( face && face->charmap && face->num_glyphs )
3323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gindex = FT_Get_Char_Index( face, 0 );
3325aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( gindex == 0 || gindex >= (FT_UInt)face->num_glyphs )
3326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = FT_Get_Next_Char( face, 0, &gindex );
3327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3329aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( agindex )
3330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *agindex = gindex;
3331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_ULong )
3339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Next_Char( FT_Face   face,
3340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_ULong  charcode,
3341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_UInt  *agindex )
3342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong  result = 0;
3344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt   gindex = 0;
3345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3347aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( face && face->charmap && face->num_glyphs )
3348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt32  code = (FT_UInt32)charcode;
3350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CMap    cmap = FT_CMAP( face->charmap );
3351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3353aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      do {
3354aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        gindex = cmap->clazz->char_next( cmap, &code );
3355aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      } while ( gindex >= (FT_UInt)face->num_glyphs );
3356aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
3357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      result = ( gindex == 0 ) ? 0 : code;
3358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( agindex )
3361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *agindex = gindex;
3362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_UInt )
3370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Face_GetCharVariantIndex( FT_Face   face,
3371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_ULong  charcode,
3372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_ULong  variantSelector )
3373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  result = 0;
3375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face && face->charmap &&
3378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->charmap->encoding == FT_ENCODING_UNICODE )
3379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CharMap  charmap = find_variant_selector_charmap( face );
3381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CMap     ucmap = FT_CMAP( face->charmap );
3382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charmap != NULL )
3385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_CMap  vcmap = FT_CMAP( charmap );
3387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3389295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( charcode > 0xFFFFFFFFUL )
3390295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
3391295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
3392295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3393295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
3394295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( variantSelector > 0xFFFFFFFFUL )
3395295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
3396295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
3397295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
3398295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
3399295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
3400295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        result = vcmap->clazz->char_var_index( vcmap, ucmap,
3401295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                               (FT_UInt32)charcode,
3402295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                               (FT_UInt32)variantSelector );
3403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Int )
3413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Face_GetCharVariantIsDefault( FT_Face   face,
3414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   FT_ULong  charcode,
3415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   FT_ULong  variantSelector )
3416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int  result = -1;
3418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face )
3421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CharMap  charmap = find_variant_selector_charmap( face );
3423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charmap != NULL )
3426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_CMap  vcmap = FT_CMAP( charmap );
3428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3430295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( charcode > 0xFFFFFFFFUL )
3431295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
3432295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
3433295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3434295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
3435295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( variantSelector > 0xFFFFFFFFUL )
3436295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
3437295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
3438295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
3439295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
3440295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
3441295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        result = vcmap->clazz->char_var_default( vcmap,
3442295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                                 (FT_UInt32)charcode,
3443295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                                 (FT_UInt32)variantSelector );
3444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_UInt32* )
3454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Face_GetVariantSelectors( FT_Face  face )
3455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  *result = NULL;
3457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face )
3460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CharMap  charmap = find_variant_selector_charmap( face );
3462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charmap != NULL )
3465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_CMap    vcmap  = FT_CMAP( charmap );
3467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Memory  memory = FT_FACE_MEMORY( face );
3468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = vcmap->clazz->variant_list( vcmap, memory );
3471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_UInt32* )
3481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Face_GetVariantsOfChar( FT_Face   face,
3482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             FT_ULong  charcode )
3483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  *result = NULL;
3485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face )
3488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CharMap  charmap = find_variant_selector_charmap( face );
3490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charmap != NULL )
3493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_CMap    vcmap  = FT_CMAP( charmap );
3495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Memory  memory = FT_FACE_MEMORY( face );
3496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3498295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( charcode > 0xFFFFFFFFUL )
3499295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
3500295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
3501295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3502295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
3503295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
3504295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        result = vcmap->clazz->charvariant_list( vcmap, memory,
3505295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                                 (FT_UInt32)charcode );
3506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_UInt32* )
3515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Face_GetCharsOfVariant( FT_Face   face,
3516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             FT_ULong  variantSelector )
3517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  *result = NULL;
3519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face )
3522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CharMap  charmap = find_variant_selector_charmap( face );
3524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charmap != NULL )
3527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_CMap    vcmap  = FT_CMAP( charmap );
3529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Memory  memory = FT_FACE_MEMORY( face );
3530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3532295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( variantSelector > 0xFFFFFFFFUL )
3533295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
3534295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
3535295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
3536295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
3537295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
3538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = vcmap->clazz->variantchar_list( vcmap, memory,
3539295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                                 (FT_UInt32)variantSelector );
3540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_UInt )
3550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Name_Index( FT_Face     face,
3551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_String*  glyph_name )
3552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  result = 0;
3554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face && FT_HAS_GLYPH_NAMES( face ) )
3557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Service_GlyphDict  service;
3559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FACE_LOOKUP_SERVICE( face,
3562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              service,
3563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              GLYPH_DICT );
3564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( service && service->name_index )
3566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = service->name_index( face, glyph_name );
3567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Glyph_Name( FT_Face     face,
3577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_UInt     glyph_index,
3578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Pointer  buffer,
3579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_UInt     buffer_max )
3580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error = FT_Err_Invalid_Argument;
3582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* clean up buffer */
3585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( buffer && buffer_max > 0 )
3586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ((FT_Byte*)buffer)[0] = 0;
3587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face                                     &&
3589295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner         (FT_Long)glyph_index <= face->num_glyphs &&
3590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_HAS_GLYPH_NAMES( face )               )
3591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Service_GlyphDict  service;
3593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FACE_LOOKUP_SERVICE( face,
3596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              service,
3597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              GLYPH_DICT );
3598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( service && service->get_name )
3600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = service->get_name( face, glyph_index, buffer, buffer_max );
3601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
3604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( const char* )
3610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Postscript_Name( FT_Face  face )
3611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const char*  result = NULL;
3613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
3616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
3617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !result )
3619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Service_PsFontName  service;
3621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FACE_LOOKUP_SERVICE( face,
3624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              service,
3625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              POSTSCRIPT_FONT_NAME );
3626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( service && service->get_ps_font_name )
3628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = service->get_ps_font_name( face );
3629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
3632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in tttables.h */
3637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void* )
3639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Sfnt_Table( FT_Face      face,
3640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Sfnt_Tag  tag )
3641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    void*                  table = 0;
3643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Service_SFNT_Table  service;
3644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face && FT_IS_SFNT( face ) )
3647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
3649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( service != NULL )
3650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        table = service->get_table( face, tag );
3651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return table;
3654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in tttables.h */
3658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Load_Sfnt_Table( FT_Face    face,
3661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ULong   tag,
3662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Long    offset,
3663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Byte*   buffer,
3664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ULong*  length )
3665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Service_SFNT_Table  service;
3667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face || !FT_IS_SFNT( face ) )
3670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Face_Handle;
3671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
3673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( service == NULL )
3674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Unimplemented_Feature;
3675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return service->load_table( face, tag, offset, buffer, length );
3677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in tttables.h */
3681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Sfnt_Table_Info( FT_Face    face,
3684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_UInt    table_index,
3685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ULong  *tag,
3686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ULong  *length )
3687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Service_SFNT_Table  service;
3689295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_ULong               offset;
3690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face || !FT_IS_SFNT( face ) )
3693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Face_Handle;
3694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
3696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( service == NULL )
3697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Unimplemented_Feature;
3698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3699295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    return service->table_info( face, table_index, tag, &offset, length );
3700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in tttables.h */
3704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_ULong )
3706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_CMap_Language_ID( FT_CharMap  charmap )
3707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Service_TTCMaps  service;
3709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face             face;
3710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_CMapInfo         cmap_info;
3711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !charmap || !charmap->face )
3714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
3715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face = charmap->face;
3717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FACE_FIND_SERVICE( face, service, TT_CMAP );
3718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( service == NULL )
3719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
3720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( service->get_cmap_info( charmap, &cmap_info ))
3721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
3722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return cmap_info.language;
3724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in tttables.h */
3728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Long )
3730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_CMap_Format( FT_CharMap  charmap )
3731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Service_TTCMaps  service;
3733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face             face;
3734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_CMapInfo         cmap_info;
3735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !charmap || !charmap->face )
3738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return -1;
3739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face = charmap->face;
3741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FACE_FIND_SERVICE( face, service, TT_CMAP );
3742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( service == NULL )
3743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return -1;
3744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( service->get_cmap_info( charmap, &cmap_info ))
3745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return -1;
3746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return cmap_info.format;
3748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftsizes.h */
3752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Activate_Size( FT_Size  size )
3755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face  face;
3757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( size == NULL )
376077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      return FT_Err_Invalid_Argument;
3761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face = size->face;
3763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face == NULL || face->driver == NULL )
376477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      return FT_Err_Invalid_Argument;
3765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* we don't need anything more complex than that; all size objects */
3767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* are already listed by the face                                  */
3768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->size = size;
3769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Ok;
3771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
3775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
3776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
3777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
3778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
3779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                        R E N D E R E R S                        ****/
3780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
3781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
3782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
3783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
3784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
3785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* lookup a renderer by glyph format in the library's list */
3787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Renderer )
3788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Lookup_Renderer( FT_Library       library,
3789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Glyph_Format  format,
3790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ListNode*     node )
3791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ListNode  cur;
3793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Renderer  result = 0;
3794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
3797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
3798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur = library->renderers.head;
3800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( node )
3802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( *node )
3804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cur = (*node)->next;
3805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *node = 0;
3806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( cur )
3809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Renderer  renderer = FT_RENDERER( cur->data );
3811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( renderer->glyph_format == format )
3814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( node )
3816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *node = cur;
3817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = renderer;
3819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
3820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur = cur->next;
3822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
3825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Renderer
3830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_lookup_glyph_renderer( FT_GlyphSlot  slot )
3831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face      face    = slot->face;
3833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Library   library = FT_FACE_LIBRARY( face );
3834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Renderer  result  = library->cur_renderer;
3835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !result || result->glyph_format != slot->format )
3838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      result = FT_Lookup_Renderer( library, slot->format, 0 );
3839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
3845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_set_current_renderer( FT_Library  library )
3846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Renderer  renderer;
3848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, 0 );
3851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library->cur_renderer = renderer;
3852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
3856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_add_renderer( FT_Module  module )
3857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Library   library = module->library;
3859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory    memory  = library->memory;
3860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error;
3861aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_ListNode  node    = NULL;
3862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( node ) )
3865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
3866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Renderer         render = FT_RENDERER( module );
3869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Renderer_Class*  clazz  = (FT_Renderer_Class*)module->clazz;
3870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      render->clazz        = clazz;
3873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      render->glyph_format = clazz->glyph_format;
3874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* allocate raster object if needed */
3876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
3877aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich           clazz->raster_class->raster_new                )
3878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = clazz->raster_class->raster_new( memory, &render->raster );
3880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
3881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
3882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        render->raster_render = clazz->raster_class->raster_render;
3884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        render->render        = clazz->render_glyph;
3885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* add to list */
3888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      node->data = module;
3889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_List_Add( &library->renderers, node );
3890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_set_current_renderer( library );
3892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
3895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
3896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( node );
3897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
3899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
3900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
3904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_remove_renderer( FT_Module  module )
3905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Library   library = module->library;
3907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory    memory  = library->memory;
3908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ListNode  node;
3909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node = FT_List_Find( &library->renderers, module );
3912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( node )
3913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Renderer  render = FT_RENDERER( module );
3915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* release raster object, if any */
3918aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( render->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
3919aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich           render->raster                                         )
3920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        render->clazz->raster_class->raster_done( render->raster );
3921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* remove from list */
3923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_List_Remove( &library->renderers, node );
3924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( node );
3925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_set_current_renderer( library );
3927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftrender.h */
3932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Renderer )
3934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Renderer( FT_Library       library,
3935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Glyph_Format  format )
3936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `library' delayed to FT_Lookup_Renderer() */
3938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Lookup_Renderer( library, format, 0 );
3940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftrender.h */
3944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Set_Renderer( FT_Library     library,
3947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Renderer    renderer,
3948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_UInt        num_params,
3949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Parameter*  parameters )
3950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ListNode  node;
3952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error = FT_Err_Ok;
3953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
3956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Library_Handle;
3957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !renderer )
3959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Argument;
3960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node = FT_List_Find( &library->renderers, renderer );
3962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !node )
3963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Err_Invalid_Argument;
3965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
3966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_List_Up( &library->renderers, node );
3969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( renderer->glyph_format == FT_GLYPH_FORMAT_OUTLINE )
3971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      library->cur_renderer = renderer;
3972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( num_params > 0 )
3974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Renderer_SetModeFunc  set_mode = renderer->clazz->set_mode;
3976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; num_params > 0; num_params-- )
3979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = set_mode( renderer, parameters->tag, parameters->data );
3981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
3982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
3983aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        parameters++;
3984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
3988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
3989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
3993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Render_Glyph_Internal( FT_Library      library,
3994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_GlyphSlot    slot,
3995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_Render_Mode  render_mode )
3996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error = FT_Err_Ok;
3998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Renderer  renderer;
3999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if it is already a bitmap, no need to do anything */
4002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    switch ( slot->format )
4003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_GLYPH_FORMAT_BITMAP:   /* already a bitmap, don't do anything */
4005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
4006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    default:
4008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ListNode  node   = 0;
4010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Bool      update = 0;
4011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* small shortcut for the very common case */
4014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
4015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
4016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          renderer = library->cur_renderer;
4017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          node     = library->renderers.head;
4018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
4019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
4020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          renderer = FT_Lookup_Renderer( library, slot->format, &node );
4021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = FT_Err_Unimplemented_Feature;
4023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        while ( renderer )
4024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
4025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          error = renderer->render( renderer, slot, render_mode, NULL );
4026aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          if ( !error                                               ||
4027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_ERROR_BASE( error ) != FT_Err_Cannot_Render_Glyph )
4028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            break;
4029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* FT_Err_Cannot_Render_Glyph is returned if the render mode   */
4031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* is unsupported by the current renderer for this glyph image */
4032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* format.                                                     */
4033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* now, look for another renderer that supports the same */
4035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* format.                                               */
4036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          renderer = FT_Lookup_Renderer( library, slot->format, &node );
4037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          update   = 1;
4038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
4039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* if we changed the current renderer for the glyph image format */
4041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* we need to select it as the next current one                  */
4042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !error && update && renderer )
4043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Set_Renderer( library, renderer, 0, 0 );
4044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
4048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
4052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
4054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Render_Glyph( FT_GlyphSlot    slot,
4055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Render_Mode  render_mode )
4056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Library  library;
4058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4060aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( !slot || !slot->face )
4061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Argument;
4062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library = FT_FACE_LIBRARY( slot->face );
4064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Render_Glyph_Internal( library, slot, render_mode );
4066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                         M O D U L E S                           ****/
4075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
4084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
4085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Destroy_Module                                                     */
4086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
4087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
4088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Destroys a given module object.  For drivers, this also destroys   */
4089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    all child faces.                                                   */
4090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
4091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <InOut>                                                               */
409241371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier  /*    module :: A handle to the target driver object.                    */
4093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
4094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Note>                                                                */
409541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier  /*    The driver _must_ be LOCKED!                                       */
4096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
4097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
4098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Destroy_Module( FT_Module  module )
4099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory         memory  = module->memory;
4101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module_Class*  clazz   = module->clazz;
4102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Library        library = module->library;
4103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( library && library->auto_hinter == module )
4106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      library->auto_hinter = 0;
4107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if the module is a renderer */
4109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_RENDERER( module ) )
4110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_remove_renderer( module );
4111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if the module is a font driver, add some steps */
4113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_DRIVER( module ) )
4114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      Destroy_Driver( FT_DRIVER( module ) );
4115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* finalize the module object */
4117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->module_done )
4118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      clazz->module_done( module );
4119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* discard it */
4121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( module );
4122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
4128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Add_Module( FT_Library              library,
4129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const FT_Module_Class*  clazz )
4130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
4132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory;
4133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module  module;
4134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt    nn;
4135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FREETYPE_VER_FIXED  ( ( (FT_Long)FREETYPE_MAJOR << 16 ) | \
4138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                FREETYPE_MINOR                  )
4139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
4141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Library_Handle;
4142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !clazz )
4144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Argument;
4145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check freetype version */
4147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->module_requires > FREETYPE_VER_FIXED )
4148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Version;
4149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* look for a module with the same name in the library's table */
4151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( nn = 0; nn < library->num_modules; nn++ )
4152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      module = library->modules[nn];
4154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ft_strcmp( module->clazz->module_name, clazz->module_name ) == 0 )
4155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* this installed module has the same name, compare their versions */
4157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( clazz->module_version <= module->clazz->module_version )
4158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return FT_Err_Lower_Module_Version;
4159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* remove the module from our list, then exit the loop to replace */
4161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* it by our new version..                                        */
4162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Remove_Module( library, module );
4163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
4164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = library->memory;
4168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error  = FT_Err_Ok;
4169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( library->num_modules >= FT_MAX_MODULES )
4171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Err_Too_Many_Drivers;
4173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
4174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* allocate module object */
4177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( module, clazz->module_size ) )
4178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
4179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* base initialization */
4181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    module->library = library;
4182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    module->memory  = memory;
4183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    module->clazz   = (FT_Module_Class*)clazz;
4184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check whether the module is a renderer - this must be performed */
4186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* before the normal module initialization                         */
4187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_RENDERER( module ) )
4188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* add to the renderers list */
4190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = ft_add_renderer( module );
4191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
4192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
4193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* is the module a auto-hinter? */
4196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_HINTER( module ) )
4197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      library->auto_hinter = module;
4198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if the module is a font driver */
4200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_DRIVER( module ) )
4201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* allocate glyph loader if needed */
4203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Driver  driver = FT_DRIVER( module );
4204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      driver->clazz = (FT_Driver_Class)module->clazz;
4207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_DRIVER_USES_OUTLINES( driver ) )
4208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = FT_GlyphLoader_New( memory, &driver->glyph_loader );
4210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
4211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
4212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->module_init )
4216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = clazz->module_init( module );
4218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
4219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
4220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* add module to the library's table */
4223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library->modules[library->num_modules++] = module;
4224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
4226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
4227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
4229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_DRIVER( module ) )
4230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Driver  driver = FT_DRIVER( module );
4232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_DRIVER_USES_OUTLINES( driver ) )
4235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_GlyphLoader_Done( driver->glyph_loader );
4236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_RENDERER( module ) )
4239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Renderer  renderer = FT_RENDERER( module );
4241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4243aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      if ( renderer->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
4244aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich           renderer->raster                                         )
4245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        renderer->clazz->raster_class->raster_done( renderer->raster );
4246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( module );
4249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
4250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Module )
4256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Module( FT_Library   library,
4257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const char*  module_name )
4258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module   result = 0;
4260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module*  cur;
4261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module*  limit;
4262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library || !module_name )
4265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return result;
4266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur   = library->modules;
4268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    limit = cur + library->num_modules;
4269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; cur < limit; cur++ )
4271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ft_strcmp( cur[0]->clazz->module_name, module_name ) == 0 )
4272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = cur[0];
4274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
4275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
4278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
4282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( const void* )
4284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Module_Interface( FT_Library   library,
4285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           const char*  mod_name )
4286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module  module;
4288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `library' delayed to FT_Get_Module() */
4291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    module = FT_Get_Module( library, mod_name );
4293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return module ? module->clazz->module_interface : 0;
4295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Pointer )
4299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_module_get_service( FT_Module    module,
4300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         const char*  service_id )
4301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pointer  result = NULL;
4303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( module )
4305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ASSERT( module->clazz && module->clazz->get_interface );
4307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     /* first, look for the service in the module
4309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      */
4310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( module->clazz->get_interface )
4311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = module->clazz->get_interface( module, service_id );
4312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( result == NULL )
4314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project       /* we didn't find it, look in all other modules then
4316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        */
4317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Library  library = module->library;
4318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Module*  cur     = library->modules;
4319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Module*  limit   = cur + library->num_modules;
4320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
432141371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier
4322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( ; cur < limit; cur++ )
4323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
4324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( cur[0] != module )
4325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
4326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_ASSERT( cur[0]->clazz );
4327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( cur[0]->clazz->get_interface )
4329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
4330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              result = cur[0]->clazz->get_interface( cur[0], service_id );
4331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( result != NULL )
4332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                break;
4333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
4334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
4335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
4336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
4340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
4346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Remove_Module( FT_Library  library,
4347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Module   module )
4348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* try to find the module from the table, then remove it from there */
4350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
4352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Library_Handle;
4353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( module )
4355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Module*  cur   = library->modules;
4357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Module*  limit = cur + library->num_modules;
4358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; cur < limit; cur++ )
4361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( cur[0] == module )
4363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
4364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* remove it from the table */
4365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          library->num_modules--;
4366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          limit--;
4367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          while ( cur < limit )
4368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
4369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            cur[0] = cur[1];
4370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            cur++;
4371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
4372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          limit[0] = 0;
4373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* destroy the module */
4375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          Destroy_Module( module );
4376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return FT_Err_Ok;
4378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
4379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Invalid_Driver_Handle;
4382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                         L I B R A R Y                           ****/
4391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
4401aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  FT_Reference_Library( FT_Library  library )
4402aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  {
4403aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    library->refcount++;
4404aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4405aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    return FT_Err_Ok;
4406aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  }
4407aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4408aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4409aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  /* documentation is in ftmodapi.h */
4410aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4411aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  FT_EXPORT_DEF( FT_Error )
4412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_New_Library( FT_Memory    memory,
4413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Library  *alibrary )
4414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4415aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Library  library = NULL;
4416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error    error;
4417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !memory )
4420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Argument;
4421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_DEBUG_LEVEL_ERROR
4423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* init debugging support */
4424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_debug_init();
4425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
4426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* first of all, allocate the library object */
4428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( library ) )
4429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
4430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library->memory = memory;
4432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4433295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifdef FT_CONFIG_OPTION_PIC
4434295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* initialize position independent code containers */
4435295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    error = ft_pic_container_init( library );
4436295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( error )
4437295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      goto Fail;
4438295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
4439295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
4440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* allocate the render pool */
4441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library->raster_pool_size = FT_RENDER_POOL_SIZE;
4442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if FT_RENDER_POOL_SIZE > 0
4443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )
4444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
4445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
4446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4447295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    library->version_major = FREETYPE_MAJOR;
4448295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    library->version_minor = FREETYPE_MINOR;
4449295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    library->version_patch = FREETYPE_PATCH;
4450295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
4451aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    library->refcount = 1;
4452aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* That's ok now */
4454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *alibrary = library;
4455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Ok;
4457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
4459295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifdef FT_CONFIG_OPTION_PIC
4460295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    ft_pic_container_destroy( library );
4461295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
4462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( library );
4463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
4464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
4468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
4470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Library_Version( FT_Library   library,
4471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Int      *amajor,
4472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Int      *aminor,
4473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Int      *apatch )
4474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int  major = 0;
4476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int  minor = 0;
4477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int  patch = 0;
4478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( library )
4481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      major = library->version_major;
4483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      minor = library->version_minor;
4484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      patch = library->version_patch;
4485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( amajor )
4488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *amajor = major;
4489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( aminor )
4491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *aminor = minor;
4492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( apatch )
4494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *apatch = patch;
4495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
4501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Done_Library( FT_Library  library )
4502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory;
4504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
4507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Invalid_Library_Handle;
4508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4509aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    library->refcount--;
4510aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( library->refcount > 0 )
4511aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      goto Exit;
4512aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = library->memory;
4514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4515aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    /*
4516aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     * Close all faces in the library.  If we don't do this, we can have
4517aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     * some subtle memory leaks.
4518aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     *
4519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * Example:
4520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
4521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  - the cff font driver uses the pshinter module in cff_size_done
4522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  - if the pshinter module is destroyed before the cff font driver,
4523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *    opened FT_Face objects managed by the driver are not properly
4524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *    destroyed, resulting in a memory leak
4525aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     *
4526aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     * Some faces are dependent on other faces, like Type42 faces that
4527aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     * depend on TrueType faces synthesized internally.
4528aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     *
4529aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     * The order of drivers should be specified in driver_name[].
4530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     */
4531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4532aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_UInt      m, n;
4533aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      const char*  driver_name[] = { "type42", NULL };
4534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4536aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      for ( m = 0;
4537aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            m < sizeof ( driver_name ) / sizeof ( driver_name[0] );
4538aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            m++ )
4539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4540aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        for ( n = 0; n < library->num_modules; n++ )
4541aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
4542aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_Module    module      = library->modules[n];
4543aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          const char*  module_name = module->clazz->module_name;
4544aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_List      faces;
4545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4547aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          if ( driver_name[m]                                &&
4548aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich               ft_strcmp( module_name, driver_name[m] ) != 0 )
4549aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            continue;
4550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4551aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          if ( ( module->clazz->module_flags & FT_MODULE_FONT_DRIVER ) == 0 )
4552aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            continue;
4553aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4554aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_TRACE7(( "FT_Done_Library: close faces for %s\n", module_name ));
4555aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4556aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          faces = &FT_DRIVER( module )->faces_list;
4557aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          while ( faces->head )
4558aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          {
4559aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            FT_Done_Face( FT_FACE( faces->head->data ) );
4560aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            if ( faces->head )
4561aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich              FT_TRACE0(( "FT_Done_Library: failed to free some faces\n" ));
4562aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          }
456377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        }
4564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Close all other modules in the library */
4568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 1
4569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* XXX Modules are removed in the reversed order so that  */
4570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* type42 module is removed before truetype module.  This */
4571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* avoids double free in some occasions.  It is a hack.   */
4572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( library->num_modules > 0 )
4573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Remove_Module( library,
4574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        library->modules[library->num_modules - 1] );
4575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
4576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt  n;
4578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( n = 0; n < library->num_modules; n++ )
4581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Module  module = library->modules[n];
4583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( module )
4586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
4587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          Destroy_Module( module );
4588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          library->modules[n] = 0;
4589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
4590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
4593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Destroy raster objects */
4595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( library->raster_pool );
4596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library->raster_pool_size = 0;
4597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4598295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifdef FT_CONFIG_OPTION_PIC
4599295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* Destroy pic container contents */
4600295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    ft_pic_container_destroy( library );
4601295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
4602295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
4603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( library );
4604aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4605aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  Exit:
4606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Ok;
4607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
4613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Set_Debug_Hook( FT_Library         library,
4614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_UInt            hook_index,
4615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_DebugHook_Func  debug_hook )
4616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( library && debug_hook &&
4618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         hook_index <
4619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) )
4620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      library->debug_hooks[hook_index] = debug_hook;
4621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_TrueTypeEngineType )
4627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_TrueType_Engine_Type( FT_Library  library )
4628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TrueTypeEngineType  result = FT_TRUETYPE_ENGINE_TYPE_NONE;
4630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( library )
4633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Module  module = FT_Get_Module( library, "truetype" );
4635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( module )
4638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Service_TrueTypeEngine  service;
4640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        service = (FT_Service_TrueTypeEngine)
4643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    ft_module_get_service( module,
4644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           FT_SERVICE_ID_TRUETYPE_ENGINE );
4645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( service )
4646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result = service->engine_type;
4647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
4651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
4655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
4657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_stub_set_char_sizes( FT_Size     size,
4658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_F26Dot6  width,
4659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_F26Dot6  height,
4660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_UInt     horz_res,
4661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_UInt     vert_res )
4662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Size_RequestRec  req;
4664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver           driver = size->face->driver;
4665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( driver->clazz->request_size )
4668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      req.type   = FT_SIZE_REQUEST_TYPE_NOMINAL;
4670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      req.width  = width;
4671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      req.height = height;
4672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( horz_res == 0 )
4674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        horz_res = vert_res;
4675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( vert_res == 0 )
4677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        vert_res = horz_res;
4678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( horz_res == 0 )
4680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        horz_res = vert_res = 72;
4681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      req.horiResolution = horz_res;
4683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      req.vertResolution = vert_res;
4684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return driver->clazz->request_size( size, &req );
4686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
4689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
4693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_stub_set_pixel_sizes( FT_Size  size,
4694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_UInt  width,
4695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_UInt  height )
4696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Size_RequestRec  req;
4698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver           driver = size->face->driver;
4699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( driver->clazz->request_size )
4702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      req.type           = FT_SIZE_REQUEST_TYPE_NOMINAL;
4704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      req.width          = width  << 6;
4705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      req.height         = height << 6;
4706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      req.horiResolution = 0;
4707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      req.vertResolution = 0;
4708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return driver->clazz->request_size( size, &req );
4710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
4713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
4716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4718aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  /* documentation is in freetype.h */
4719aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
4721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_SubGlyph_Info( FT_GlyphSlot  glyph,
4722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_UInt       sub_index,
4723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Int       *p_index,
4724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_UInt      *p_flags,
4725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Int       *p_arg1,
4726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Int       *p_arg2,
4727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Matrix    *p_transform )
4728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error = FT_Err_Invalid_Argument;
4730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4732aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( glyph                                      &&
4733aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         glyph->subglyphs                           &&
4734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         glyph->format == FT_GLYPH_FORMAT_COMPOSITE &&
4735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         sub_index < glyph->num_subglyphs           )
4736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_SubGlyph  subg = glyph->subglyphs + sub_index;
4738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *p_index     = subg->index;
4741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *p_flags     = subg->flags;
4742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *p_arg1      = subg->arg1;
4743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *p_arg2      = subg->arg2;
4744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *p_transform = subg->transform;
4745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
4748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
4752