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/*                                                                         */
79c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod/*  Copyright 1996-2014 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
32727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include FT_SERVICE_PROPERTIES_H
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_SERVICE_SFNT_H
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_SERVICE_POSTSCRIPT_NAME_H
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_SERVICE_GLYPH_DICT_H
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_SERVICE_TT_CMAP_H
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_SERVICE_KERNING_H
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_SERVICE_TRUETYPE_ENGINE_H
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
40295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifdef FT_CONFIG_OPTION_MAC_FONTS
4177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#include "ftbase.h"
42295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
44727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
45727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef FT_DEBUG_LEVEL_TRACE
46727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
47727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include FT_BITMAP_H
48727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
49727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#if defined( _MSC_VER )      /* Visual C++ (and Intel C++)   */
50727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* We disable the warning `conversion from XXX to YYY,     */
51727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* possible loss of data' in order to compile cleanly with */
52727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* the maximum level of warnings: `md5.c' is non-FreeType  */
53727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* code, and it gets used during development builds only.  */
54727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#pragma warning( push )
55727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#pragma warning( disable : 4244 )
56727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* _MSC_VER */
57727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
58727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* it's easiest to include `md5.c' directly */
59727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "md5.c"
60727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
61727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#if defined( _MSC_VER )
62727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#pragma warning( pop )
63727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif
64727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
65727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* FT_DEBUG_LEVEL_TRACE */
66727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
67727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define GRID_FIT_METRICS
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
7077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Pointer )
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_service_list_lookup( FT_ServiceDesc  service_descriptors,
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          const char*     service_id )
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pointer      result = NULL;
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ServiceDesc  desc   = service_descriptors;
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( desc && service_id )
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; desc->serv_id != NULL; desc++ )
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ft_strcmp( desc->serv_id, service_id ) == 0 )
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result = (FT_Pointer)desc->serv_data;
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_validator_init( FT_Validator        valid,
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     const FT_Byte*      base,
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     const FT_Byte*      limit,
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_ValidationLevel  level )
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    valid->base  = base;
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    valid->limit = limit;
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    valid->level = level;
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    valid->error = FT_Err_Ok;
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Int )
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_validator_run( FT_Validator  valid )
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* This function doesn't work!  None should call it. */
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( valid );
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return -1;
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_validator_error( FT_Validator  valid,
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Error      error )
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* since the cast below also disables the compiler's */
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* type check, we introduce a dummy variable, which  */
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* will be optimized away                            */
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    volatile ft_jmp_buf* jump_buffer = &valid->jump_buffer;
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    valid->error = error;
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* throw away volatileness; use `jump_buffer' or the  */
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* compiler may warn about an unused local variable   */
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_longjmp( *(ft_jmp_buf*) jump_buffer, 1 );
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                           S T R E A M                           ****/
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* create a new input stream from an FT_Open_Args structure */
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                          */
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_New( FT_Library           library,
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const FT_Open_Args*  args,
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Stream           *astream )
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory;
158aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_Stream  stream = NULL;
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
16177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    *astream = 0;
16277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
164727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Library_Handle );
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !args )
167727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
169aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    memory = library->memory;
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( stream ) )
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->memory = memory;
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( args->flags & FT_OPEN_MEMORY )
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* create a memory-based stream */
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_OpenMemory( stream,
180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            (const FT_Byte*)args->memory_base,
181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            args->memory_size );
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
183aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
184aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT
185aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( args->flags & FT_OPEN_PATHNAME )
187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* create a normal system stream */
189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Stream_Open( stream, args->pathname );
190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->pathname.pointer = args->pathname;
191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream )
193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* use an existing, user-provided stream */
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* in this case, we do not need to allocate a new stream object */
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* since the caller is responsible for closing it himself       */
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( stream );
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream = args->stream;
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
201aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
202aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif
203aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
205727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Invalid_Argument );
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( stream );
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->memory = memory;  /* just to be certain */
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *astream = stream;
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_Free( FT_Stream  stream,
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Int     external )
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream )
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Memory  memory = stream->memory;
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_Close( stream );
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !external )
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FREE( stream );
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
23677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /*************************************************************************/
23777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /*                                                                       */
23877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
23977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
24077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* messages during execution.                                            */
24177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /*                                                                       */
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_objs
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****               FACE, SIZE & GLYPH SLOT OBJECTS                   ****/
252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_init( FT_GlyphSlot  slot )
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
262aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Driver         driver   = slot->face->driver;
263aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Driver_Class   clazz    = driver->clazz;
264aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Memory         memory   = driver->root.memory;
265aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Error          error    = FT_Err_Ok;
266aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Slot_Internal  internal = NULL;
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->library = driver->root.library;
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( internal ) )
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->internal = internal;
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_DRIVER_USES_OUTLINES( driver ) )
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_GlyphLoader_New( memory, &internal->loader );
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error && clazz->init_slot )
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = clazz->init_slot( slot );
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_free_bitmap( FT_GlyphSlot  slot )
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
29077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Memory  memory = FT_FACE_MEMORY( slot->face );
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( slot->bitmap.buffer );
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* assume that the bitmap buffer was stolen or not */
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* allocated from the heap                         */
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->bitmap.buffer = NULL;
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_set_bitmap( FT_GlyphSlot  slot,
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_Byte*      buffer )
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_glyphslot_free_bitmap( slot );
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap.buffer = buffer;
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( (slot->internal->flags & FT_GLYPH_OWN_BITMAP) == 0 );
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_alloc_bitmap( FT_GlyphSlot  slot,
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             FT_ULong      size )
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = FT_FACE_MEMORY( slot->face );
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( slot->bitmap.buffer );
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (void)FT_ALLOC( slot->bitmap.buffer, size );
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_clear( FT_GlyphSlot  slot )
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* free bitmap if needed */
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_glyphslot_free_bitmap( slot );
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* clear all public fields in the glyph slot */
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ZERO( &slot->metrics );
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ZERO( &slot->outline );
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap.width      = 0;
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap.rows       = 0;
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap.pitch      = 0;
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap.pixel_mode = 0;
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* `slot->bitmap.buffer' has been handled by ft_glyphslot_free_bitmap */
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap_left   = 0;
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap_top    = 0;
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->num_subglyphs = 0;
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->subglyphs     = 0;
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->control_data  = 0;
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->control_len   = 0;
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->other         = 0;
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->format        = FT_GLYPH_FORMAT_NONE;
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->linearHoriAdvance = 0;
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->linearVertAdvance = 0;
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->lsb_delta         = 0;
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->rsb_delta         = 0;
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_done( FT_GlyphSlot  slot )
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver        driver = slot->face->driver;
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz  = driver->clazz;
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory        memory = driver->root.memory;
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->done_slot )
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      clazz->done_slot( slot );
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* free bitmap buffer if needed */
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_glyphslot_free_bitmap( slot );
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
383295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* slot->internal might be NULL in out-of-memory situations */
384295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( slot->internal )
385295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    {
386aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* free glyph loader */
387aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( FT_DRIVER_USES_OUTLINES( driver ) )
388aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      {
389aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        FT_GlyphLoader_Done( slot->internal->loader );
390aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        slot->internal->loader = 0;
391aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      }
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
393aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_FREE( slot->internal );
394295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    }
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_New_GlyphSlot( FT_Face        face,
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_GlyphSlot  *aslot )
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error         error;
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver        driver;
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz;
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory        memory;
408aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_GlyphSlot     slot = NULL;
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face || !face->driver )
412727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    driver = face->driver;
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clazz  = driver->clazz;
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = driver->root.memory;
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" ));
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_ALLOC( slot, clazz->slot_object_size ) )
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->face = face;
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = ft_glyphslot_init( slot );
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ft_glyphslot_done( slot );
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FREE( slot );
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->next  = face->glyph;
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->glyph = slot;
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( aslot )
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *aslot = slot;
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( aslot )
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *aslot = 0;
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error ));
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Done_GlyphSlot( FT_GlyphSlot  slot )
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( slot )
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Driver     driver = slot->face->driver;
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Memory     memory = driver->root.memory;
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphSlot  prev;
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphSlot  cur;
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Remove slot from its parent face's list */
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      prev = NULL;
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur  = slot->face->glyph;
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( cur )
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( cur == slot )
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( !prev )
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            slot->face->glyph = cur->next;
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          else
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            prev->next = cur->next;
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
47341371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier          /* finalize client-specific data */
47441371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier          if ( slot->generic.finalizer )
47541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier            slot->generic.finalizer( slot );
47641371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ft_glyphslot_done( slot );
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_FREE( slot );
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        prev = cur;
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cur  = cur->next;
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Set_Transform( FT_Face     face,
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Matrix*  matrix,
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Vector*  delta )
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face_Internal  internal;
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    internal = face->internal;
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    internal->transform_flags = 0;
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !matrix )
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.xx = 0x10000L;
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.xy = 0;
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.yx = 0;
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.yy = 0x10000L;
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      matrix = &internal->transform_matrix;
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix = *matrix;
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* set transform_flags bit flag 0 if `matrix' isn't the identity */
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ( matrix->xy | matrix->yx ) ||
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         matrix->xx != 0x10000L      ||
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         matrix->yy != 0x10000L      )
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_flags |= 1;
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !delta )
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_delta.x = 0;
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_delta.y = 0;
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta = &internal->transform_delta;
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_delta = *delta;
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* set transform_flags bit flag 1 if `delta' isn't the null vector */
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( delta->x | delta->y )
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_flags |= 2;
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Renderer
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_lookup_glyph_renderer( FT_GlyphSlot  slot );
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef GRID_FIT_METRICS
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_grid_fit_metrics( FT_GlyphSlot  slot,
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 FT_Bool       vertical )
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Glyph_Metrics*  metrics = &slot->metrics;
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pos             right, bottom;
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( vertical )
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX );
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY );
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      right  = FT_PIX_CEIL( metrics->vertBearingX + metrics->width );
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bottom = FT_PIX_CEIL( metrics->vertBearingY + metrics->height );
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->width  = right - metrics->vertBearingX;
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->height = bottom - metrics->vertBearingY;
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      right  = FT_PIX_CEIL ( metrics->horiBearingX + metrics->width );
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bottom = FT_PIX_FLOOR( metrics->horiBearingY - metrics->height );
571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX );
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY );
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->width  = right - metrics->horiBearingX;
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->height = metrics->horiBearingY - bottom;
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance );
580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance );
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* GRID_FIT_METRICS */
583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Load_Glyph( FT_Face   face,
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_UInt   glyph_index,
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Int32  load_flags )
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error      error;
593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver     driver;
594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphSlot  slot;
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Library    library;
59677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Bool       autohint = FALSE;
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module     hinter;
598aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    TT_Face       ttface = (TT_Face)face;
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face || !face->size || !face->glyph )
602727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* The validity test for `glyph_index' is performed by the */
605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* font drivers.                                           */
606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot = face->glyph;
608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_glyphslot_clear( slot );
609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    driver  = face->driver;
611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library = driver->root.library;
612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hinter  = library->auto_hinter;
613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* resolve load flags dependencies */
615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( load_flags & FT_LOAD_NO_RECURSE )
617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      load_flags |= FT_LOAD_NO_SCALE         |
618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_LOAD_IGNORE_TRANSFORM;
619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( load_flags & FT_LOAD_NO_SCALE )
621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      load_flags |= FT_LOAD_NO_HINTING |
623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_LOAD_NO_BITMAP;
624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      load_flags &= ~FT_LOAD_RENDER;
626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*
629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * Determine whether we need to auto-hint or not.
630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * The general rules are:
631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
632295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     * - Do only auto-hinting if we have a hinter module, a scalable font
633295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     *   format dealing with outlines, and no transforms except simple
634295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     *   slants and/or rotations by integer multiples of 90 degrees.
635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
636295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't
637295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     *   have a native font hinter.
638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
639aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner     * - Otherwise, auto-hint for LIGHT hinting mode or if there isn't
640aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner     *   any hinting bytecode in the TrueType/OpenType font.
641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
642295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     * - Exception: The font is `tricky' and requires the native hinter to
643295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     *   load properly.
644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     */
645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
646aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( hinter                                           &&
647aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         !( load_flags & FT_LOAD_NO_HINTING )             &&
648aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         !( load_flags & FT_LOAD_NO_AUTOHINT )            &&
649aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         FT_DRIVER_IS_SCALABLE( driver )                  &&
650aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         FT_DRIVER_USES_OUTLINES( driver )                &&
651aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         !FT_IS_TRICKY( face )                            &&
652bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly         ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM )    ||
653bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly           ( face->internal->transform_matrix.yx == 0 &&
654295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner             face->internal->transform_matrix.xx != 0 ) ||
655295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner           ( face->internal->transform_matrix.xx == 0 &&
656295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner             face->internal->transform_matrix.yx != 0 ) ) )
65777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    {
65877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) ||
65977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner           !FT_DRIVER_HAS_HINTER( driver )         )
66077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        autohint = TRUE;
661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Render_Mode  mode = FT_LOAD_TARGET_MODE( load_flags );
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
666aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        /* the check for `num_locations' assures that we actually    */
667aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        /* test for instructions in a TTF and not in a CFF-based OTF */
668ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        /*                                                           */
669ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        /* since `maxSizeOfInstructions' might be unreliable, we     */
670ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        /* check the size of the `fpgm' and `prep' tables, too --    */
671ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        /* the assumption is that there don't exist real TTFs where  */
672ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        /* both `fpgm' and `prep' tables are missing                 */
673aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        if ( mode == FT_RENDER_MODE_LIGHT                       ||
674aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner             face->internal->ignore_unpatented_hinter           ||
675aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner             ( FT_IS_SFNT( face )                             &&
676aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner               ttface->num_locations                          &&
677ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease               ttface->max_profile.maxSizeOfInstructions == 0 &&
678ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease               ttface->font_program_size == 0                 &&
679ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease               ttface->cvt_program_size == 0                  ) )
68077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          autohint = TRUE;
681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( autohint )
685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
686727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_AutoHinter_Interface  hinting;
687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* try to load embedded bitmaps first if available            */
690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*                                                            */
691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* XXX: This is really a temporary hack that should disappear */
692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*      promptly with FreeType 2.1!                           */
693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*                                                            */
694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_HAS_FIXED_SIZES( face )             &&
695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = driver->clazz->load_glyph( slot, face->size,
698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           glyph_index,
699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           load_flags | FT_LOAD_SBITS_ONLY );
700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !error && slot->format == FT_GLYPH_FORMAT_BITMAP )
702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Load_Ok;
703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Face_Internal  internal        = face->internal;
707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int            transform_flags = internal->transform_flags;
708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* since the auto-hinter calls FT_Load_Glyph by itself, */
711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* make sure that glyphs aren't transformed             */
712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        internal->transform_flags = 0;
713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* load auto-hinted outline */
715727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        hinting = (FT_AutoHinter_Interface)hinter->clazz->module_interface;
716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error   = hinting->load_glyph( (FT_AutoHinter)hinter,
718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       slot, face->size,
719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       glyph_index, load_flags );
720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        internal->transform_flags = transform_flags;
722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = driver->clazz->load_glyph( slot,
727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                         face->size,
728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                         glyph_index,
729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                         load_flags );
730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* check that the loaded outline is correct */
736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = FT_Outline_Check( &slot->outline );
737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef GRID_FIT_METRICS
741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !( load_flags & FT_LOAD_NO_HINTING ) )
742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ft_glyphslot_grid_fit_metrics( slot,
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              FT_BOOL( load_flags & FT_LOAD_VERTICAL_LAYOUT ) );
744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Load_Ok:
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* compute the advance */
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->advance.x = 0;
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->advance.y = slot->metrics.vertAdvance;
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->advance.x = slot->metrics.horiAdvance;
758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->advance.y = 0;
759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* compute the linear advance in 16.16 pixels */
762aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 &&
763aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         ( FT_IS_SCALABLE( face ) )                  )
764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Size_Metrics*  metrics = &face->size->metrics;
766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* it's tricky! */
769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance,
770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           metrics->x_scale, 64 );
771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->linearVertAdvance = FT_MulDiv( slot->linearVertAdvance,
773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           metrics->y_scale, 64 );
774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) == 0 )
777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Face_Internal  internal = face->internal;
779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* now, transform the glyph image if needed */
782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( internal->transform_flags )
783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* get renderer */
785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Renderer  renderer = ft_lookup_glyph_renderer( slot );
786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( renderer )
789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          error = renderer->clazz->transform_glyph(
790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                     renderer, slot,
791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                     &internal->transform_matrix,
792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                     &internal->transform_delta );
793295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
794295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
795295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          /* apply `standard' transformation if no renderer is available */
796bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          if ( internal->transform_flags & 1 )
797295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            FT_Outline_Transform( &slot->outline,
798295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                  &internal->transform_matrix );
799295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
800bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          if ( internal->transform_flags & 2 )
801295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            FT_Outline_Translate( &slot->outline,
802295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                  internal->transform_delta.x,
803295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                  internal->transform_delta.y );
804295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
805295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* transform advance */
807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Vector_Transform( &slot->advance, &internal->transform_matrix );
808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
811295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_TRACE5(( "  x advance: %d\n" , slot->advance.x ));
812295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_TRACE5(( "  y advance: %d\n" , slot->advance.y ));
813295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
814295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_TRACE5(( "  linear x advance: %d\n" , slot->linearHoriAdvance ));
815295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_TRACE5(( "  linear y advance: %d\n" , slot->linearVertAdvance ));
816295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* do we need to render the image now? */
818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error                                    &&
819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         slot->format != FT_GLYPH_FORMAT_BITMAP    &&
820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         slot->format != FT_GLYPH_FORMAT_COMPOSITE &&
821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         load_flags & FT_LOAD_RENDER )
822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Render_Mode  mode = FT_LOAD_TARGET_MODE( load_flags );
824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( mode == FT_RENDER_MODE_NORMAL      &&
827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           (load_flags & FT_LOAD_MONOCHROME ) )
828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        mode = FT_RENDER_MODE_MONO;
829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Render_Glyph( slot, mode );
831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Load_Char( FT_Face   face,
842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_ULong  char_code,
843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Int32  load_flags )
844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  glyph_index;
846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
849727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    glyph_index = (FT_UInt)char_code;
852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->charmap )
853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph_index = FT_Get_Char_Index( face, char_code );
854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Load_Glyph( face, glyph_index, load_flags );
856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* destructor for sizes list */
860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  destroy_size( FT_Memory  memory,
862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Size    size,
863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Driver  driver )
864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* finalize client-specific data */
866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( size->generic.finalizer )
867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      size->generic.finalizer( size );
868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* finalize format-specific stuff */
870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( driver->clazz->done_size )
871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      driver->clazz->done_size( size );
872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( size->internal );
874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( size );
875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_cmap_done_internal( FT_CMap  cmap );
880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  destroy_charmaps( FT_Face    face,
884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Memory  memory )
885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int  n;
887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( n = 0; n < face->num_charmaps; n++ )
893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CMap  cmap = FT_CMAP( face->charmaps[n] );
895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_cmap_done_internal( cmap );
898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->charmaps[n] = NULL;
900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( face->charmaps );
903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->num_charmaps = 0;
904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* destructor for faces list */
908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  destroy_face( FT_Memory  memory,
910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Face    face,
911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Driver  driver )
912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz = driver->clazz;
914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* discard auto-hinting data */
917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->autohint.finalizer )
918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->autohint.finalizer( face->autohint.data );
919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Discard glyph slots for this face.                           */
921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Beware!  FT_Done_GlyphSlot() changes the field `face->glyph' */
922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( face->glyph )
923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Done_GlyphSlot( face->glyph );
924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* discard all sizes for this face */
926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_List_Finalize( &face->sizes_list,
927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      (FT_List_Destructor)destroy_size,
928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      memory,
929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      driver );
930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->size = 0;
931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* now discard client data */
933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->generic.finalizer )
934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->generic.finalizer( face );
935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* discard charmaps */
937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    destroy_charmaps( face, memory );
938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* finalize format-specific stuff */
940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->done_face )
941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      clazz->done_face( face );
942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* close the stream for this face if needed */
944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream_Free(
945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->stream,
946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->stream = 0;
949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* get rid of it */
951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->internal )
952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( face->internal );
954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( face );
956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Destroy_Driver( FT_Driver  driver )
961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_List_Finalize( &driver->faces_list,
963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      (FT_List_Destructor)destroy_face,
964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      driver->root.memory,
965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      driver );
966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check whether we need to drop the driver's glyph loader */
968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_DRIVER_USES_OUTLINES( driver ) )
969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphLoader_Done( driver->glyph_loader );
970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    find_unicode_charmap                                               */
977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    This function finds a Unicode charmap, if there is one.            */
980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    And if there is more than one, it tries to favour the more         */
981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    extensive one, i.e., one that supports UCS-4 against those which   */
982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    are limited to the BMP (said UCS-2 encoding.)                      */
983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    This function is called from open_face() (just below), and also    */
985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ).                */
986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  find_unicode_charmap( FT_Face  face )
989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  first;
991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  cur;
992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* caller should have already checked that `face' is valid */
995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( face );
996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    first = face->charmaps;
998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !first )
1000727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_CharMap_Handle );
1001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*
1003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  The original TrueType specification(s) only specified charmap
1004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  formats that are capable of mapping 8 or 16 bit character codes to
1005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  glyph indices.
1006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
1007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  However, recent updates to the Apple and OpenType specifications
1008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  introduced new formats that are capable of mapping 32-bit character
1009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  codes as well.  And these are already used on some fonts, mainly to
1010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  map non-BMP Asian ideographs as defined in Unicode.
1011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
1012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  For compatibility purposes, these fonts generally come with
1013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  *several* Unicode charmaps:
1014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
1015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *   - One of them in the "old" 16-bit format, that cannot access
1016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *     all glyphs in the font.
1017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
1018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *   - Another one in the "new" 32-bit format, that can access all
1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *     the glyphs.
1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
1021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  This function has been written to always favor a 32-bit charmap
1022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  when found.  Otherwise, a 16-bit one is returned when found.
1023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     */
1024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Since the `interesting' table, with IDs (3,10), is normally the */
1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* last one, we loop backwards.  This loses with type1 fonts with  */
1027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* non-BMP characters (<.0001%), this wins with .ttf with non-BMP  */
1028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* chars (.01% ?), and this is the same about 99.99% of the time!  */
1029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur = first + face->num_charmaps;  /* points after the last one */
1031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; --cur >= first; )
1033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur[0]->encoding == FT_ENCODING_UNICODE )
1035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* XXX If some new encodings to represent UCS-4 are added, */
1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /*     they should be added here.                          */
1038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT &&
1039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               cur[0]->encoding_id == TT_MS_ID_UCS_4        )     ||
1040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE &&
1041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32    ) )
1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1043aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE
1044aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )
1045aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          {
1046aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            FT_ERROR(( "find_unicode_charmap: UCS-4 cmap is found "
1047aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                       "at too late position (%d)\n", cur - first ));
1048aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            continue;
1049aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          }
1050aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
1051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          face->charmap = cur[0];
1052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return FT_Err_Ok;
1053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* We do not have any UCS-4 charmap.                */
1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Do the loop again and search for UCS-2 charmaps. */
1059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur = first + face->num_charmaps;
1060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; --cur >= first; )
1062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur[0]->encoding == FT_ENCODING_UNICODE )
1064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1065aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE
1066aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )
1067aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
1068aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_ERROR(( "find_unicode_charmap: UCS-2 cmap is found "
1069aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                     "at too late position (%d)\n", cur - first ));
1070aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          continue;
1071aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        }
1072aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
1073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->charmap = cur[0];
1074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return FT_Err_Ok;
1075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1078727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_THROW( Invalid_CharMap_Handle );
1079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
1085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    find_variant_selector_charmap                                      */
1086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
1088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    This function finds the variant selector charmap, if there is one. */
1089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    There can only be one (platform=0, specific=5, format=14).         */
1090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_CharMap
1092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  find_variant_selector_charmap( FT_Face  face )
1093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  first;
1095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  end;
1096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  cur;
1097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* caller should have already checked that `face' is valid */
1100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( face );
1101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    first = face->charmaps;
1103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !first )
1105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return NULL;
1106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    end = first + face->num_charmaps;  /* points after the last one */
1108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( cur = first; cur < end; ++cur )
1110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE    &&
1112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR &&
1113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           FT_Get_CMap_Format( cur[0] ) == 14                  )
11147f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      {
1115aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE
1116aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )
1117aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
1118aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_ERROR(( "find_unicode_charmap: UVS cmap is found "
1119aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                     "at too late position (%d)\n", cur - first ));
1120aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          continue;
1121aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        }
1122aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
1123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return cur[0];
11247f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      }
1125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return NULL;
1128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
1134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    open_face                                                          */
1135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
1137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    This function does some work for FT_Open_Face().                   */
1138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  open_face( FT_Driver      driver,
1141ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease             FT_Stream      *astream,
1142ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease             FT_Bool        external_stream,
1143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Long        face_index,
1144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Int         num_params,
1145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Parameter*  params,
1146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Face       *aface )
1147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory         memory;
1149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class   clazz;
1150ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    FT_Face           face     = NULL;
1151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face_Internal  internal = NULL;
1152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1153ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    FT_Error          error, error2;
1154ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clazz  = driver->clazz;
1157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = driver->root.memory;
1158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* allocate the face object and perform basic initialization */
1160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( face, clazz->face_object_size ) )
1161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
1162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1163ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    face->driver = driver;
1164ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    face->memory = memory;
1165ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    face->stream = *astream;
1166ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1167ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */
1168ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    if ( external_stream )
1169ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;
1170ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( internal ) )
1172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->internal = internal;
1175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_CONFIG_OPTION_INCREMENTAL
1177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      int  i;
1179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->internal->incremental_interface = 0;
1182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( i = 0; i < num_params && !face->internal->incremental_interface;
1183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            i++ )
1184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL )
1185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          face->internal->incremental_interface =
1186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            (FT_Incremental_Interface)params[i].data;
1187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
1189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->init_face )
1191ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      error = clazz->init_face( *astream,
1192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                face,
1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                (FT_Int)face_index,
1194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                num_params,
1195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                params );
1196ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    *astream = face->stream; /* Stream may have been changed. */
1197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
1199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* select Unicode charmap by default */
1201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error2 = find_unicode_charmap( face );
1202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if no Unicode charmap can be found, FT_Err_Invalid_CharMap_Handle */
1204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* is returned.                                                      */
1205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* no error should happen, but we want to play safe */
1207727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( error2 && FT_ERR_NEQ( error2, Invalid_CharMap_Handle ) )
1208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = error2;
1210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
1211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *aface = face;
1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
1216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      destroy_charmaps( face, memory );
1219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( clazz->done_face )
1220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        clazz->done_face( face );
1221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( internal );
1222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( face );
1223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *aface = 0;
1224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* there's a Mac-specific extended implementation of FT_New_Face() */
1231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* in src/base/ftmac.c                                             */
1232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
123341371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#ifndef FT_MACINTOSH
1234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
1236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
1238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_New_Face( FT_Library   library,
1239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               const char*  pathname,
1240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Long      face_index,
1241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Face     *aface )
1242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Open_Args  args;
1244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `library' and `aface' delayed to FT_Open_Face() */
1247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !pathname )
1248727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
1249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.flags    = FT_OPEN_PATHNAME;
1251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.pathname = (char*)pathname;
125277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    args.stream   = NULL;
1253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Open_Face( library, &args, face_index, aface );
1255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
125741371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#endif
1258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
1261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
1263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_New_Memory_Face( FT_Library      library,
1264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      const FT_Byte*  file_base,
1265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Long         file_size,
1266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Long         face_index,
1267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Face        *aface )
1268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Open_Args  args;
1270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `library' and `face' delayed to FT_Open_Face() */
1273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !file_base )
1274727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
1275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.flags       = FT_OPEN_MEMORY;
1277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.memory_base = file_base;
1278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.memory_size = file_size;
127977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    args.stream      = NULL;
1280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Open_Face( library, &args, face_index, aface );
1282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
128577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#ifdef FT_CONFIG_OPTION_MAC_FONTS
1286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The behavior here is very similar to that in base/ftmac.c, but it     */
1288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* is designed to work on non-mac systems, so no mac specific calls.     */
1289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* We look at the file and determine if it is a mac dfont file or a mac  */
1291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* resource file, or a macbinary file containing a mac resource file.    */
1292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Unlike ftmac I'm not going to look at a `FOND'.  I don't really see   */
1294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* the point, especially since there may be multiple `FOND' resources.   */
1295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Instead I'll just look for `sfnt' and `POST' resources, ordered as    */
1296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* they occur in the file.                                               */
1297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Note that multiple `POST' resources do not mean multiple postscript   */
1299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* fonts; they all get jammed together to make what is essentially a     */
1300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* pfb file.                                                             */
1301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* We aren't interested in `NFNT' or `FONT' bitmap resources.            */
1303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* As soon as we get an `sfnt' load it into memory and pass it off to    */
1305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* FT_Open_Face.                                                         */
1306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* If we have a (set of) `POST' resources, massage them into a (memory)  */
1308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* pfb file and pass that to FT_Open_Face.  (As with ftmac.c I'm not     */
1309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* going to try to save the kerning info.  After all that lives in the   */
1310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* `FOND' which isn't in the file containing the `POST' resources so     */
1311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* we don't really have access to it.                                    */
1312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
131477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* Finalizer for a memory stream; gets called by FT_Done_Face(). */
131577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* It frees the memory it uses.                                  */
131677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* From ftmac.c.                                                 */
1317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  memory_stream_close( FT_Stream  stream )
1319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = stream->memory;
1321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( stream->base );
1324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->size  = 0;
1326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->base  = 0;
1327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->close = 0;
1328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Create a new memory stream from a buffer and a size. */
133277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* From ftmac.c.                                        */
1333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  new_memory_stream( FT_Library           library,
1335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Byte*             base,
1336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_ULong             size,
1337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream_CloseFunc  close,
1338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream           *astream )
1339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
1341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory;
1342aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_Stream  stream = NULL;
1343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
1346727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Library_Handle );
1347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !base )
1349727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
1350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *astream = 0;
1352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = library->memory;
1353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( stream ) )
1354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream_OpenMemory( stream, base, size );
1357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->close = close;
1359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *astream = stream;
1361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Create a new FT_Face given a buffer and a driver name. */
1368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* from ftmac.c */
136977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  FT_LOCAL_DEF( FT_Error )
1370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  open_face_from_buffer( FT_Library   library,
1371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Byte*     base,
1372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_ULong     size,
1373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Long      face_index,
1374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         const char*  driver_name,
1375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Face     *aface )
1376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Open_Args  args;
1378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error      error;
1379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream     stream = NULL;
1380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory     memory = library->memory;
1381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = new_memory_stream( library,
1384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               base,
1385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               size,
1386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               memory_stream_close,
1387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               &stream );
1388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( base );
1391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
1392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.flags = FT_OPEN_STREAM;
1395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.stream = stream;
1396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( driver_name )
1397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      args.flags = args.flags | FT_OPEN_DRIVER;
1399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      args.driver = FT_Get_Module( library, driver_name );
1400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
140277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#ifdef FT_MACINTOSH
140377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* At this point, face_index has served its purpose;      */
140477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* whoever calls this function has already used it to     */
140577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* locate the correct font data.  We should not propagate */
140677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* this index to FT_Open_Face() (unless it is negative).  */
140777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
140877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( face_index > 0 )
140977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      face_index = 0;
141077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#endif
141177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
1412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Open_Face( library, &args, face_index, aface );
1413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error == FT_Err_Ok )
1415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
1416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
141777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#ifdef FT_MACINTOSH
141877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      FT_Stream_Free( stream, 0 );
141977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#else
1420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_Close( stream );
1422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( stream );
1423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
142477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#endif
1425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
143077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* Look up `TYP1' or `CID ' table from sfnt table directory.       */
143177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* `offset' and `length' must exclude the binary header in tables. */
143277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
143377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */
143477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* format too.  Here, since we can't expect that the TrueType font */
143577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* driver is loaded unconditially, we must parse the font by       */
143677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* ourselves.  We are only interested in the name of the table and */
143777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* the offset.                                                     */
143877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
143977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  static FT_Error
144077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  ft_lookup_PS_in_sfnt_stream( FT_Stream  stream,
144177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                               FT_Long    face_index,
144277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                               FT_ULong*  offset,
144377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                               FT_ULong*  length,
144477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                               FT_Bool*   is_sfnt_cid )
144577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  {
144677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Error   error;
144777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_UShort  numTables;
144877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Long    pstable_index;
144977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_ULong   tag;
145077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    int        i;
145177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
145277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
145377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    *offset = 0;
145477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    *length = 0;
145577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    *is_sfnt_cid = FALSE;
145677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
145777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* TODO: support for sfnt-wrapped PS/CID in TTC format */
145877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
145977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* version check for 'typ1' (should be ignored?) */
146077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( FT_READ_ULONG( tag ) )
146177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      return error;
146277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( tag != TTAG_typ1 )
1463727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unknown_File_Format );
146477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
146577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( FT_READ_USHORT( numTables ) )
146677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      return error;
146777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( FT_STREAM_SKIP( 2 * 3 ) ) /* skip binary search header */
146877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      return error;
146977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
147077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    pstable_index = -1;
147177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    *is_sfnt_cid  = FALSE;
147277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
147377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    for ( i = 0; i < numTables; i++ )
147477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    {
147577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      if ( FT_READ_ULONG( tag )     || FT_STREAM_SKIP( 4 )      ||
147677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner           FT_READ_ULONG( *offset ) || FT_READ_ULONG( *length ) )
147777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        return error;
147877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
147977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      if ( tag == TTAG_CID )
148077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      {
148177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        pstable_index++;
148277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        *offset += 22;
148377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        *length -= 22;
148477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        *is_sfnt_cid = TRUE;
148577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        if ( face_index < 0 )
148677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          return FT_Err_Ok;
148777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      }
148877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      else if ( tag == TTAG_TYP1 )
148977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      {
149077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        pstable_index++;
149177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        *offset += 24;
149277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        *length -= 24;
149377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        *is_sfnt_cid = FALSE;
149477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        if ( face_index < 0 )
149577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          return FT_Err_Ok;
149677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      }
149777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      if ( face_index >= 0 && pstable_index == face_index )
149877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        return FT_Err_Ok;
149977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    }
1500727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_THROW( Table_Missing );
150177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  }
150277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
150377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
150477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  FT_LOCAL_DEF( FT_Error )
150577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  open_face_PS_from_sfnt_stream( FT_Library     library,
150677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                 FT_Stream      stream,
150777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                 FT_Long        face_index,
150877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                 FT_Int         num_params,
150977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                 FT_Parameter  *params,
151077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                 FT_Face       *aface )
151177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  {
151277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Error   error;
151377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Memory  memory = library->memory;
151477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_ULong   offset, length;
151577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Long    pos;
151677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Bool    is_sfnt_cid;
1517aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_Byte*   sfnt_ps = NULL;
151877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
151977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_UNUSED( num_params );
152077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_UNUSED( params );
152177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
152277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
152377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    pos = FT_Stream_Pos( stream );
152477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
152577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    error = ft_lookup_PS_in_sfnt_stream( stream,
152677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                         face_index,
152777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                         &offset,
152877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                         &length,
152977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                         &is_sfnt_cid );
153077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( error )
153177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      goto Exit;
153277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
153377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( FT_Stream_Seek( stream, pos + offset ) )
153477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      goto Exit;
153577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
153677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) )
153777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      goto Exit;
153877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
153977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length );
154077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( error )
154177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      goto Exit;
154277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
154377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    error = open_face_from_buffer( library,
154477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                   sfnt_ps,
154577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                   length,
1546727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                   FT_MIN( face_index, 0 ),
154777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                   is_sfnt_cid ? "cid" : "type1",
154877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                   aface );
154977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  Exit:
155077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    {
155177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      FT_Error  error1;
155277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
155377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
1554727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( FT_ERR_EQ( error, Unknown_File_Format ) )
155577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      {
155677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        error1 = FT_Stream_Seek( stream, pos );
155777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        if ( error1 )
155877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          return error1;
155977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      }
156077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
156177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      return error;
156277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    }
156377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  }
156477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
156577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
156641371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#ifndef FT_MACINTOSH
156777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
1568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The resource header says we've got resource_cnt `POST' (type1) */
1569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* resources in this file.  They all need to be coalesced into    */
1570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* one lump which gets passed on to the type1 driver.             */
1571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Here can be only one PostScript font in a file so face_index   */
1572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* must be 0 (or -1).                                             */
1573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                */
1574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Mac_Read_POST_Resource( FT_Library  library,
1576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Stream   stream,
1577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Long    *offsets,
1578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Long     resource_cnt,
1579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Long     face_index,
1580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Face    *aface )
1581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1582727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error   error  = FT_ERR( Cannot_Open_Resource );
1583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = library->memory;
1584aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_Byte*   pfb_data = NULL;
1585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int        i, type, flags;
1586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    len;
1587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    pfb_len, pfb_pos, pfb_lenpos;
1588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    rlen, temp;
1589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face_index == -1 )
1592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face_index = 0;
1593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face_index != 0 )
1594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
1595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Find the length of all the POST resources, concatenated.  Assume */
1597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* worst case (each resource in its own section).                   */
1598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_len = 0;
1599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0; i < resource_cnt; ++i )
1600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Stream_Seek( stream, offsets[i] );
1602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_READ_LONG( temp ) )
1605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pfb_len += temp + 6;
1607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) )
1610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[0] = 0x80;
1613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[1] = 1;            /* Ascii section */
1614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[2] = 0;            /* 4-byte length, fill in later */
1615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[3] = 0;
1616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[4] = 0;
1617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[5] = 0;
1618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_pos     = 6;
1619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_lenpos  = 2;
1620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    len = 0;
1622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    type = 1;
1623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0; i < resource_cnt; ++i )
1624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Stream_Seek( stream, offsets[i] );
1626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit2;
1628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_READ_LONG( rlen ) )
1629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_READ_USHORT( flags ) )
1631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1632aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n",
1633aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                   i, offsets[i], rlen, flags ));
1634aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1635aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* postpone the check of rlen longer than buffer until FT_Stream_Read() */
1636aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( ( flags >> 8 ) == 0 )        /* Comment, should not be loaded */
1637aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        continue;
1638aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1639aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* the flags are part of the resource, so rlen >= 2.  */
1640aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* but some fonts declare rlen = 0 for empty fragment */
1641aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( rlen > 2 )
1642aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        rlen -= 2;
1643aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      else
1644aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        rlen = 0;
1645aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ( flags >> 8 ) == type )
1647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        len += rlen;
1648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
1649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1650aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( pfb_lenpos + 3 > pfb_len + 2 )
1651aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          goto Exit2;
1652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_lenpos    ] = (FT_Byte)( len );
1653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
1654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
1655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 );
1656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ( flags >> 8 ) == 5 )      /* End of font mark */
1658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
1659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1660aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( pfb_pos + 6 > pfb_len + 2 )
1661aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          goto Exit2;
1662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_pos++] = 0x80;
1663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        type = flags >> 8;
1665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        len = rlen;
1666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_pos++] = (FT_Byte)type;
1668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_lenpos          = pfb_pos;
1669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_pos++] = 0;        /* 4-byte length, fill in later */
1670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_pos++] = 0;
1671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_pos++] = 0;
1672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_pos++] = 0;
1673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1675727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_ERR( Cannot_Open_Resource );
1676aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len )
1677aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        goto Exit2;
1678aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen );
1680aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( error )
1681aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        goto Exit2;
1682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pfb_pos += rlen;
1683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1685aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( pfb_pos + 2 > pfb_len + 2 )
1686aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      goto Exit2;
1687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[pfb_pos++] = 0x80;
1688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[pfb_pos++] = 3;
1689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1690aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( pfb_lenpos + 3 > pfb_len + 2 )
1691aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      goto Exit2;
1692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[pfb_lenpos    ] = (FT_Byte)( len );
1693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
1694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
1695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 );
1696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return open_face_from_buffer( library,
1698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  pfb_data,
1699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  pfb_pos,
1700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  face_index,
1701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  "type1",
1702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  aface );
1703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit2:
1705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( pfb_data );
1706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The resource header says we've got resource_cnt `sfnt'      */
1713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* (TrueType/OpenType) resources in this file.  Look through   */
1714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* them for the one indicated by face_index, load it into mem, */
1715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* pass it on the the truetype driver and return it.           */
1716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                             */
1717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Mac_Read_sfnt_Resource( FT_Library  library,
1719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Stream   stream,
1720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Long    *offsets,
1721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Long     resource_cnt,
1722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Long     face_index,
1723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Face    *aface )
1724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = library->memory;
1726aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_Byte*   sfnt_data = NULL;
1727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
1728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    flag_offset;
1729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    rlen;
1730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int        is_cff;
1731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    face_index_in_resource = 0;
1732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face_index == -1 )
1735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face_index = 0;
1736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face_index >= resource_cnt )
1737727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Cannot_Open_Resource );
1738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    flag_offset = offsets[face_index];
1740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_Seek( stream, flag_offset );
1741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_READ_LONG( rlen ) )
1745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( rlen == -1 )
1747727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Cannot_Open_Resource );
1748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
174977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    error = open_face_PS_from_sfnt_stream( library,
175077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                           stream,
175177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                           face_index,
175277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                           0, NULL,
175377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                           aface );
175477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( !error )
175577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      goto Exit;
175677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
175777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */
175877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( FT_Stream_Seek( stream, flag_offset + 4 ) )
175977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      goto Exit;
176077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
1761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) )
1762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
1763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen );
1764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
176777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 );
1768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = open_face_from_buffer( library,
1769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   sfnt_data,
1770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   rlen,
1771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   face_index_in_resource,
1772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   is_cff ? "cff" : "truetype",
1773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   aface );
1774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Check for a valid resource fork header, or a valid dfont    */
1781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* header.  In a resource fork the first 16 bytes are repeated */
1782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* at the location specified by bytes 4-7.  In a dfont bytes   */
1783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* 4-7 point to 16 bytes of zeroes instead.                    */
1784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                             */
1785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  IsMacResource( FT_Library  library,
1787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Stream   stream,
1788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Long     resource_offset,
1789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Long     face_index,
1790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Face    *aface )
1791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = library->memory;
1793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
1794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    map_offset, rdara_pos;
1795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    *data_offsets;
1796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    count;
1797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset,
1800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       &map_offset, &rdara_pos );
1801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
1803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
18049c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    /* POST resources must be sorted to concatenate properly */
1805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Raccess_Get_DataOffsets( library, stream,
1806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                        map_offset, rdara_pos,
18079c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod                                        TTAG_POST, TRUE,
1808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                        &data_offsets, &count );
1809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
1810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = Mac_Read_POST_Resource( library, stream, data_offsets, count,
1812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      face_index, aface );
1813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( data_offsets );
1814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* POST exists in an LWFN providing a single face */
1815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !error )
1816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        (*aface)->num_faces = 1;
1817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
1818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
18209c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    /* sfnt resources should not be sorted to preserve the face order by
18219c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod       QuickDraw API */
1822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Raccess_Get_DataOffsets( library, stream,
1823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                        map_offset, rdara_pos,
18249c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod                                        TTAG_sfnt, FALSE,
1825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                        &data_offsets, &count );
1826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
1827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Long  face_index_internal = face_index % count;
1829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = Mac_Read_sfnt_Resource( library, stream, data_offsets, count,
1832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      face_index_internal, aface );
1833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( data_offsets );
1834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !error )
1835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        (*aface)->num_faces = count;
1836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Check for a valid macbinary header, and if we find one   */
1843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* check that the (flattened) resource fork in it is valid. */
1844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                          */
1845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  IsMacBinary( FT_Library  library,
1847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Stream   stream,
1848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Long     face_index,
1849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Face    *aface )
1850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned char  header[128];
1852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error       error;
1853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long        dlen, offset;
1854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( NULL == stream )
1857727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Stream_Operation );
1858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_Seek( stream, 0 );
1860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_Read( stream, (FT_Byte*)header, 128 );
1864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (            header[ 0] !=  0 ||
1868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    header[74] !=  0 ||
1869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    header[82] !=  0 ||
1870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    header[ 1] ==  0 ||
1871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    header[ 1] >  33 ||
1872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    header[63] !=  0 ||
1873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         header[2 + header[1]] !=  0 )
1874727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unknown_File_Format );
1875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    dlen = ( header[0x53] << 24 ) |
1877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           ( header[0x54] << 16 ) |
1878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           ( header[0x55] <<  8 ) |
1879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             header[0x56];
1880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 0
1881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    rlen = ( header[0x57] << 24 ) |
1882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           ( header[0x58] << 16 ) |
1883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           ( header[0x59] <<  8 ) |
1884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             header[0x5a];
1885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* 0 */
1886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    offset = 128 + ( ( dlen + 127 ) & ~127 );
1887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return IsMacResource( library, stream, offset, face_index, aface );
1889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  load_face_in_embedded_rfork( FT_Library           library,
1897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_Stream            stream,
1898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_Long              face_index,
1899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_Face             *aface,
1900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               const FT_Open_Args  *args )
1901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
1904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_raccess
1905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = library->memory;
1907727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error   error  = FT_ERR( Unknown_File_Format );
1908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int        i;
1909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    char *     file_names[FT_RACCESS_N_RULES];
1911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    offsets[FT_RACCESS_N_RULES];
1912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   errors[FT_RACCESS_N_RULES];
19137f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    FT_Bool    is_darwin_vfs, vfs_rfork_has_no_font = FALSE; /* not tested */
1914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Open_Args  args2;
191677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Stream     stream2 = 0;
1917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Raccess_Guess( library, stream,
1920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      args->pathname, file_names, offsets, errors );
1921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
1923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
192441371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      is_darwin_vfs = ft_raccess_rule_by_darwin_vfs( library, i );
19257f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      if ( is_darwin_vfs && vfs_rfork_has_no_font )
19267f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      {
19277f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        FT_TRACE3(( "Skip rule %d: darwin vfs resource fork"
19287f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner                    " is already checked and"
19297f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner                    " no font is found\n", i ));
19307f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        continue;
1931aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      }
19327f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
1933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( errors[i] )
1934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i ));
1936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        continue;
1937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      args2.flags    = FT_OPEN_PATHNAME;
1940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      args2.pathname = file_names[i] ? file_names[i] : args->pathname;
1941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_TRACE3(( "Try rule %d: %s (offset=%d) ...",
1943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  i, args2.pathname, offsets[i] ));
1944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Stream_New( library, &args2, &stream2 );
1946727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( is_darwin_vfs && FT_ERR_EQ( error, Cannot_Open_Stream ) )
19477f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        vfs_rfork_has_no_font = TRUE;
19487f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
1949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_TRACE3(( "failed\n" ));
1952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        continue;
1953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = IsMacResource( library, stream2, offsets[i],
1956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             face_index, aface );
1957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_Free( stream2, 0 );
1958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_TRACE3(( "%s\n", error ? "failed": "successful" ));
1960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !error )
1962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
19637f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      else if ( is_darwin_vfs )
19647f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner          vfs_rfork_has_no_font = TRUE;
1965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for (i = 0; i < FT_RACCESS_N_RULES; i++)
1968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( file_names[i] )
1970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FREE( file_names[i] );
1971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Caller (load_mac_face) requires FT_Err_Unknown_File_Format. */
1974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1975727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_ERR( Unknown_File_Format );
1976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
1980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_objs
1981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
198577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* Check for some macintosh formats without Carbon framework.    */
1986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Is this a macbinary file?  If so look at the resource fork.   */
1987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Is this a mac dfont file?                                     */
1988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Is this an old style resource fork? (in data)                 */
1989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Else call load_face_in_embedded_rfork to try extra rules      */
1990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* (defined in `ftrfork.c').                                     */
1991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                               */
1992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  load_mac_face( FT_Library           library,
1994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Stream            stream,
1995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Long              face_index,
1996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Face             *aface,
1997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const FT_Open_Args  *args )
1998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error error;
2000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( args );
2001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = IsMacBinary( library, stream, face_index, aface );
2004727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( FT_ERR_EQ( error, Unknown_File_Format ) )
2005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
2008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_raccess
2009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_TRACE3(( "Try as dfont: %s ...", args->pathname ));
2011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = IsMacResource( library, stream, 0, face_index, aface );
2013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_TRACE3(( "%s\n", error ? "failed" : "successful" ));
2015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
2017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_objs
2018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2021727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( ( FT_ERR_EQ( error, Unknown_File_Format )      ||
2022727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           FT_ERR_EQ( error, Invalid_Stream_Operation ) ) &&
2023727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease         ( args->flags & FT_OPEN_PATHNAME )               )
2024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = load_face_in_embedded_rfork( library, stream,
2025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           face_index, aface, args );
2026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
202877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#endif
2029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif  /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */
2031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Open_Face( FT_Library           library,
2037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                const FT_Open_Args*  args,
2038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Long              face_index,
2039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Face             *aface )
2040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error;
2042ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    FT_Driver    driver = NULL;
2043ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    FT_Memory    memory = NULL;
2044aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Stream    stream = NULL;
2045aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Face      face   = NULL;
2046aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_ListNode  node   = NULL;
2047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bool      external_stream;
2048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module*   cur;
2049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module*   limit;
2050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `library' delayed to */
2053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* FT_Stream_New()                     */
2054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ( !aface && face_index >= 0 ) || !args )
2056727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
2057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) &&
2059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               args->stream                     );
2060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* create input stream */
2062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_New( library, args, &stream );
2063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
2064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail3;
2065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = library->memory;
2067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* If the font driver is specified in the `args' structure, use */
2069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* it.  Otherwise, we scan the list of registered drivers.      */
2070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ( args->flags & FT_OPEN_DRIVER ) && args->driver )
2071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      driver = FT_DRIVER( args->driver );
2073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* not all modules are drivers, so check... */
2075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_MODULE_IS_DRIVER( driver ) )
2076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int         num_params = 0;
2078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Parameter*  params     = 0;
2079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( args->flags & FT_OPEN_PARAMS )
2082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
2083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          num_params = args->num_params;
2084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          params     = args->params;
2085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
2086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2087ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        error = open_face( driver, &stream, external_stream, face_index,
2088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           num_params, params, &face );
2089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !error )
2090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Success;
2091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
2093727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_THROW( Invalid_Handle );
2094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_Free( stream, external_stream );
2096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
2097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
2099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2100727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_ERR( Missing_Module );
2101727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* check each font driver for an appropriate format */
2103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur   = library->modules;
2104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      limit = cur + library->num_modules;
2105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; cur < limit; cur++ )
2107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* not all modules are font drivers, so check... */
2109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_MODULE_IS_DRIVER( cur[0] ) )
2110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
2111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Int         num_params = 0;
2112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Parameter*  params     = 0;
2113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          driver = FT_DRIVER( cur[0] );
2116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( args->flags & FT_OPEN_PARAMS )
2118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
2119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            num_params = args->num_params;
2120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            params     = args->params;
2121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
2122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2123ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease          error = open_face( driver, &stream, external_stream, face_index,
2124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             num_params, params, &face );
2125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( !error )
2126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Success;
2127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
212877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#ifdef FT_CONFIG_OPTION_MAC_FONTS
212977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 &&
2130727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease               FT_ERR_EQ( error, Table_Missing )                        )
213177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          {
213277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            /* TrueType but essential tables are missing */
213377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            if ( FT_Stream_Seek( stream, 0 ) )
213477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner              break;
213577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
213677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            error = open_face_PS_from_sfnt_stream( library,
213777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                                   stream,
213877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                                   face_index,
213977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                                   num_params,
214077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                                   params,
214177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                                   aface );
214277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            if ( !error )
214377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            {
214477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner              FT_Stream_Free( stream, external_stream );
214577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner              return error;
214677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            }
214777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          }
214877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#endif
214977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
2150727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          if ( FT_ERR_NEQ( error, Unknown_File_Format ) )
2151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Fail3;
2152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
2153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2155727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    Fail3:
2156727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      /* If we are on the mac, and we get an                          */
2157727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      /* FT_Err_Invalid_Stream_Operation it may be because we have an */
2158727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      /* empty data fork, so we need to check the resource fork.      */
2159727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( FT_ERR_NEQ( error, Cannot_Open_Stream )       &&
2160727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           FT_ERR_NEQ( error, Unknown_File_Format )      &&
2161727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           FT_ERR_NEQ( error, Invalid_Stream_Operation ) )
2162727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        goto Fail2;
2163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS )
2165727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = load_mac_face( library, stream, face_index, aface, args );
2166727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( !error )
2167727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
2168727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* We don't want to go to Success here.  We've already done that. */
2169727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* On the other hand, if we succeeded we still need to close this */
2170727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* stream (we opened a different stream which extracted the       */
2171727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* interesting information out of this stream here.  That stream  */
2172727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* will still be open and the face will point to it).             */
2173727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_Stream_Free( stream, external_stream );
2174727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        return error;
2175727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
2176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2177727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( FT_ERR_NEQ( error, Unknown_File_Format ) )
2178727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        goto Fail2;
2179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif  /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */
2180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* no driver is able to handle this format */
2182727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Unknown_File_Format );
2183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail2:
2185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_Free( stream, external_stream );
2186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
2187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Success:
2190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" ));
2191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* add the face object to its driver's list */
2193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( node ) )
2194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
2195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node->data = face;
2197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* don't assume driver is the same as face->driver, so use */
2198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* face->driver instead.                                   */
2199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_List_Add( &face->driver->faces_list, node );
2200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* now allocate a glyph slot object for the face */
2202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" ));
2203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face_index >= 0 )
2205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_New_GlyphSlot( face, NULL );
2207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
2208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
2209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* finally, allocate a size object for the face */
2211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Size  size;
2213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_TRACE4(( "FT_Open_Face: Creating size object\n" ));
2216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = FT_New_Size( face, &size );
2218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
2219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
2220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->size = size;
2222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* some checks */
2226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_IS_SCALABLE( face ) )
2228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( face->height < 0 )
2230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->height = (FT_Short)-face->height;
2231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !FT_HAS_VERTICAL( face ) )
2233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->max_advance_height = (FT_Short)face->height;
2234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_HAS_FIXED_SIZES( face ) )
2237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int  i;
2239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( i = 0; i < face->num_fixed_sizes; i++ )
2242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Bitmap_Size*  bsize = face->available_sizes + i;
2244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( bsize->height < 0 )
2247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          bsize->height = (FT_Short)-bsize->height;
2248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( bsize->x_ppem < 0 )
2249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          bsize->x_ppem = (FT_Short)-bsize->x_ppem;
2250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( bsize->y_ppem < 0 )
2251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          bsize->y_ppem = -bsize->y_ppem;
2252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* initialize internal face data */
2256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Face_Internal  internal = face->internal;
2258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.xx = 0x10000L;
2261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.xy = 0;
2262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.yx = 0;
2263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.yy = 0x10000L;
2264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_delta.x = 0;
2266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_delta.y = 0;
2267aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2268aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      internal->refcount = 1;
2269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( aface )
2272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *aface = face;
2273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
2274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Done_Face( face );
2275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
2277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
2279ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    if ( node )
2280ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      FT_Done_Face( face );    /* face must be in the driver's list */
2281ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    else if ( face )
2282ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      destroy_face( memory, face, driver );
2283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
2285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE4(( "FT_Open_Face: Return %d\n", error ));
2286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Attach_File( FT_Face      face,
2295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  const char*  filepathname )
2296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Open_Args  open;
2298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `face' delayed to FT_Attach_Stream() */
2301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !filepathname )
2303727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
2304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    open.stream   = NULL;
2306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    open.flags    = FT_OPEN_PATHNAME;
2307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    open.pathname = (char*)filepathname;
2308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Attach_Stream( face, &open );
2310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Attach_Stream( FT_Face        face,
2317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Open_Args*  parameters )
2318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream  stream;
2320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
2321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver  driver;
2322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz;
2324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `parameters' delayed to FT_Stream_New() */
2327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
2329727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
2330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    driver = face->driver;
2332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !driver )
2333727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Driver_Handle );
2334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_New( driver->root.library, parameters, &stream );
2336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
2337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
2338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* we implement FT_Attach_Stream in each driver through the */
2340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* `attach_file' interface                                  */
2341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2342727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    error = FT_ERR( Unimplemented_Feature );
2343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clazz = driver->clazz;
2344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->attach_file )
2345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = clazz->attach_file( face, stream );
2346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* close the attached stream */
2348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream_Free( stream,
2349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    (FT_Bool)( parameters->stream &&
2350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               ( parameters->flags & FT_OPEN_STREAM ) ) );
2351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
2353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2360aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  FT_Reference_Face( FT_Face  face )
2361aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  {
2362aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    face->internal->refcount++;
2363aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2364aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    return FT_Err_Ok;
2365aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  }
2366aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2367aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2368aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  /* documentation is in freetype.h */
2369aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2370aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  FT_EXPORT_DEF( FT_Error )
2371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Done_Face( FT_Face  face )
2372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error;
2374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver    driver;
2375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory    memory;
2376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ListNode  node;
2377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2379727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    error = FT_ERR( Invalid_Face_Handle );
2380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face && face->driver )
2381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2382aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      face->internal->refcount--;
2383aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( face->internal->refcount > 0 )
2384aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        error = FT_Err_Ok;
2385aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      else
2386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2387aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        driver = face->driver;
2388aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        memory = driver->root.memory;
2389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2390aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        /* find face in driver's list */
2391aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        node = FT_List_Find( &driver->faces_list, face );
2392aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( node )
2393aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
2394aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          /* remove face object from the driver's list */
2395aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_List_Remove( &driver->faces_list, node );
2396aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_FREE( node );
2397aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2398aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          /* now destroy the object proper */
2399aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          destroy_face( memory, face, driver );
2400aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          error = FT_Err_Ok;
2401aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        }
2402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2404aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
2410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_New_Size( FT_Face   face,
2413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Size  *asize )
2414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error         error;
2416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory        memory;
2417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver        driver;
2418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz;
2419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Size          size = 0;
2421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ListNode      node = 0;
2422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
2425727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
2426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !asize )
2428727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Size_Handle );
2429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face->driver )
2431727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Driver_Handle );
2432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *asize = 0;
2434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    driver = face->driver;
2436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clazz  = driver->clazz;
2437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = face->memory;
2438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Allocate new size object and perform basic initialisation */
2440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( size, clazz->size_object_size ) || FT_NEW( node ) )
2441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
2442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    size->face = face;
2444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* for now, do not use any internal fields in size objects */
2446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    size->internal = 0;
2447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->init_size )
2449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = clazz->init_size( size );
2450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* in case of success, add to the face's list */
2452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
2453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *asize     = size;
2455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      node->data = size;
2456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_List_Add( &face->sizes_list, node );
2457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
2460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
2461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( node );
2463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( size );
2464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
2471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Done_Size( FT_Size  size )
2474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error;
2476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver    driver;
2477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory    memory;
2478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face      face;
2479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ListNode  node;
2480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !size )
2483727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Size_Handle );
2484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face = size->face;
2486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
2487727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
2488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    driver = face->driver;
2490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !driver )
2491727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Driver_Handle );
2492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = driver->root.memory;
2494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Err_Ok;
2496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node  = FT_List_Find( &face->sizes_list, size );
2497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( node )
2498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_List_Remove( &face->sizes_list, node );
2500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( node );
2501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( face->size == size )
2503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->size = 0;
2505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( face->sizes_list.head )
2506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          face->size = (FT_Size)(face->sizes_list.head->data);
2507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      destroy_size( memory, size, driver );
2510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
2512727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Invalid_Size_Handle );
2513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
2519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
2521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Match_Size( FT_Face          face,
2522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Size_Request  req,
2523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Bool          ignore_width,
2524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_ULong*        size_index )
2525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int   i;
2527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long  w, h;
2528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_HAS_FIXED_SIZES( face ) )
2531727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
2532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* FT_Bitmap_Size doesn't provide enough info... */
2534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )
2535727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unimplemented_Feature );
2536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    w = FT_REQUEST_WIDTH ( req );
2538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    h = FT_REQUEST_HEIGHT( req );
2539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( req->width && !req->height )
2541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      h = w;
2542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( !req->width && req->height )
2543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      w = h;
2544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    w = FT_PIX_ROUND( w );
2546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    h = FT_PIX_ROUND( h );
2547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0; i < face->num_fixed_sizes; i++ )
2549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Bitmap_Size*  bsize = face->available_sizes + i;
2551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( h != FT_PIX_ROUND( bsize->y_ppem ) )
2554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        continue;
2555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( w == FT_PIX_ROUND( bsize->x_ppem ) || ignore_width )
2557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2558727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_TRACE3(( "FT_Match_Size: bitmap strike %d matches\n", i ));
2559727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( size_index )
2561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *size_index = (FT_ULong)i;
2562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return FT_Err_Ok;
2564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2567727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_THROW( Invalid_Pixel_Size );
2568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
2572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
2574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_synthesize_vertical_metrics( FT_Glyph_Metrics*  metrics,
2575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  FT_Pos             advance )
2576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2577295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_Pos  height = metrics->height;
2578295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
2579295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
2580295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* compensate for glyph with bbox above/below the baseline */
2581295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( metrics->horiBearingY < 0 )
2582295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    {
2583295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      if ( height < metrics->horiBearingY )
2584295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        height = metrics->horiBearingY;
2585295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    }
2586295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    else if ( metrics->horiBearingY > 0 )
2587295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      height -= metrics->horiBearingY;
2588295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
2589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the factor 1.2 is a heuristical value */
2590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !advance )
2591295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      advance = height * 12 / 10;
2592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2593295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    metrics->vertBearingX = metrics->horiBearingX - metrics->horiAdvance / 2;
2594295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    metrics->vertBearingY = ( advance - height ) / 2;
2595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->vertAdvance  = advance;
2596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
2600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_recompute_scaled_metrics( FT_Face           face,
2601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_Size_Metrics*  metrics )
2602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Compute root ascender, descender, test height, and max_advance */
2604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef GRID_FIT_METRICS
2606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->ascender    = FT_PIX_CEIL( FT_MulFix( face->ascender,
2607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                   metrics->y_scale ) );
2608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->descender   = FT_PIX_FLOOR( FT_MulFix( face->descender,
2610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                    metrics->y_scale ) );
2611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->height      = FT_PIX_ROUND( FT_MulFix( face->height,
2613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                    metrics->y_scale ) );
2614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->max_advance = FT_PIX_ROUND( FT_MulFix( face->max_advance_width,
2616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                    metrics->x_scale ) );
2617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !GRID_FIT_METRICS */
2618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->ascender    = FT_MulFix( face->ascender,
2619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      metrics->y_scale );
2620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->descender   = FT_MulFix( face->descender,
2622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      metrics->y_scale );
2623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->height      = FT_MulFix( face->height,
2625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      metrics->y_scale );
2626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->max_advance = FT_MulFix( face->max_advance_width,
2628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      metrics->x_scale );
2629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* !GRID_FIT_METRICS */
2630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
2634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Select_Metrics( FT_Face   face,
2635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_ULong  strike_index )
2636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Size_Metrics*  metrics;
2638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bitmap_Size*   bsize;
2639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics = &face->size->metrics;
2642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bsize   = face->available_sizes + strike_index;
2643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->x_ppem = (FT_UShort)( ( bsize->x_ppem + 32 ) >> 6 );
2645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->y_ppem = (FT_UShort)( ( bsize->y_ppem + 32 ) >> 6 );
2646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_IS_SCALABLE( face ) )
2648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->x_scale = FT_DivFix( bsize->x_ppem,
2650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                    face->units_per_EM );
2651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->y_scale = FT_DivFix( bsize->y_ppem,
2652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                    face->units_per_EM );
2653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_recompute_scaled_metrics( face, metrics );
2655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
2657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
265877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      metrics->x_scale     = 1L << 16;
265977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      metrics->y_scale     = 1L << 16;
2660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->ascender    = bsize->y_ppem;
2661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->descender   = 0;
2662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->height      = bsize->height << 6;
2663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->max_advance = bsize->x_ppem;
2664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2665bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2666bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "FT_Select_Metrics:\n" ));
2667bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  x scale: %d (%f)\n",
2668bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                metrics->x_scale, metrics->x_scale / 65536.0 ));
2669bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  y scale: %d (%f)\n",
2670bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                metrics->y_scale, metrics->y_scale / 65536.0 ));
2671bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  ascender: %f\n",    metrics->ascender / 64.0 ));
2672bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  descender: %f\n",   metrics->descender / 64.0 ));
2673bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  height: %f\n",      metrics->height / 64.0 ));
2674bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  max advance: %f\n", metrics->max_advance / 64.0 ));
2675bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  x ppem: %d\n",      metrics->x_ppem ));
2676bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  y ppem: %d\n",      metrics->y_ppem ));
2677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
2681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Request_Metrics( FT_Face          face,
2682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Size_Request  req )
2683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Size_Metrics*  metrics;
2685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics = &face->size->metrics;
2688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_IS_SCALABLE( face ) )
2690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Long  w = 0, h = 0, scaled_w = 0, scaled_h = 0;
2692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( req->type )
2695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case FT_SIZE_REQUEST_TYPE_NOMINAL:
2697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        w = h = face->units_per_EM;
2698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
2699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case FT_SIZE_REQUEST_TYPE_REAL_DIM:
2701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        w = h = face->ascender - face->descender;
2702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
2703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case FT_SIZE_REQUEST_TYPE_BBOX:
2705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        w = face->bbox.xMax - face->bbox.xMin;
2706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        h = face->bbox.yMax - face->bbox.yMin;
2707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
2708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case FT_SIZE_REQUEST_TYPE_CELL:
2710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        w = face->max_advance_width;
2711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        h = face->ascender - face->descender;
2712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
2713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case FT_SIZE_REQUEST_TYPE_SCALES:
2715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->x_scale = (FT_Fixed)req->width;
2716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->y_scale = (FT_Fixed)req->height;
2717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !metrics->x_scale )
2718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          metrics->x_scale = metrics->y_scale;
2719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else if ( !metrics->y_scale )
2720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          metrics->y_scale = metrics->x_scale;
2721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Calculate_Ppem;
2722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case FT_SIZE_REQUEST_TYPE_MAX:
2724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
2725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* to be on the safe side */
2728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( w < 0 )
2729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        w = -w;
2730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( h < 0 )
2732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        h = -h;
2733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      scaled_w = FT_REQUEST_WIDTH ( req );
2735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      scaled_h = FT_REQUEST_HEIGHT( req );
2736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* determine scales */
2738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( req->width )
2739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->x_scale = FT_DivFix( scaled_w, w );
2741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( req->height )
2743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
2744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          metrics->y_scale = FT_DivFix( scaled_h, h );
2745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( req->type == FT_SIZE_REQUEST_TYPE_CELL )
2747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
2748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( metrics->y_scale > metrics->x_scale )
2749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              metrics->y_scale = metrics->x_scale;
2750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            else
2751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              metrics->x_scale = metrics->y_scale;
2752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
2753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
2754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
2755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
2756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          metrics->y_scale = metrics->x_scale;
2757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          scaled_h = FT_MulDiv( scaled_w, h, w );
2758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
2759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
2761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->x_scale = metrics->y_scale = FT_DivFix( scaled_h, h );
2763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        scaled_w = FT_MulDiv( scaled_h, w, h );
2764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Calculate_Ppem:
2767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* calculate the ppems */
2768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )
2769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        scaled_w = FT_MulFix( face->units_per_EM, metrics->x_scale );
2771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        scaled_h = FT_MulFix( face->units_per_EM, metrics->y_scale );
2772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->x_ppem = (FT_UShort)( ( scaled_w + 32 ) >> 6 );
2775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->y_ppem = (FT_UShort)( ( scaled_h + 32 ) >> 6 );
2776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_recompute_scaled_metrics( face, metrics );
2778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
2780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ZERO( metrics );
278277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      metrics->x_scale = 1L << 16;
278377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      metrics->y_scale = 1L << 16;
2784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2785bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2786bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "FT_Request_Metrics:\n" ));
2787bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  x scale: %d (%f)\n",
2788bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                metrics->x_scale, metrics->x_scale / 65536.0 ));
2789bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  y scale: %d (%f)\n",
2790bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                metrics->y_scale, metrics->y_scale / 65536.0 ));
2791bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  ascender: %f\n",    metrics->ascender / 64.0 ));
2792bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  descender: %f\n",   metrics->descender / 64.0 ));
2793bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  height: %f\n",      metrics->height / 64.0 ));
2794bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  max advance: %f\n", metrics->max_advance / 64.0 ));
2795bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  x ppem: %d\n",      metrics->x_ppem ));
2796bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  y ppem: %d\n",      metrics->y_ppem ));
2797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Select_Size( FT_Face  face,
2804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Int   strike_index )
2805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz;
2807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face || !FT_HAS_FIXED_SIZES( face ) )
2810727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
2811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( strike_index < 0 || strike_index >= face->num_fixed_sizes )
2813727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
2814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clazz = face->driver->clazz;
2816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->select_size )
2818bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
2819bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_Error  error;
2820bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2821bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2822bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      error = clazz->select_size( face->size, (FT_ULong)strike_index );
2823bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2824bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#ifdef FT_DEBUG_LEVEL_TRACE
2825bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      {
2826bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_Size_Metrics*  metrics = &face->size->metrics;
2827bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2828bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2829bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "FT_Select_Size (font driver's `select_size'):\n" ));
2830bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  x scale: %d (%f)\n",
2831bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                    metrics->x_scale, metrics->x_scale / 65536.0 ));
2832bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  y scale: %d (%f)\n",
2833bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                    metrics->y_scale, metrics->y_scale / 65536.0 ));
2834bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  ascender: %f\n",    metrics->ascender / 64.0 ));
2835bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  descender: %f\n",   metrics->descender / 64.0 ));
2836bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  height: %f\n",      metrics->height / 64.0 ));
2837bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  max advance: %f\n", metrics->max_advance / 64.0 ));
2838bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  x ppem: %d\n",      metrics->x_ppem ));
2839bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  y ppem: %d\n",      metrics->y_ppem ));
2840bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      }
2841bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#endif
2842bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2843bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      return error;
2844bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
2845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Select_Metrics( face, (FT_ULong)strike_index );
2847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Ok;
2849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Request_Size( FT_Face          face,
2856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Size_Request  req )
2857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz;
2859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong         strike_index;
2860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
2863727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
2864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !req || req->width < 0 || req->height < 0 ||
2866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         req->type >= FT_SIZE_REQUEST_TYPE_MAX )
2867727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
2868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clazz = face->driver->clazz;
2870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->request_size )
2872bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
2873bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_Error  error;
2874bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2875bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2876bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      error = clazz->request_size( face->size, req );
2877bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2878bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#ifdef FT_DEBUG_LEVEL_TRACE
2879bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      {
2880bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_Size_Metrics*  metrics = &face->size->metrics;
2881bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2882bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2883bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "FT_Request_Size (font driver's `request_size'):\n" ));
2884bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  x scale: %d (%f)\n",
2885bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                    metrics->x_scale, metrics->x_scale / 65536.0 ));
2886bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  y scale: %d (%f)\n",
2887bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                    metrics->y_scale, metrics->y_scale / 65536.0 ));
2888bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  ascender: %f\n",    metrics->ascender / 64.0 ));
2889bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  descender: %f\n",   metrics->descender / 64.0 ));
2890bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  height: %f\n",      metrics->height / 64.0 ));
2891bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  max advance: %f\n", metrics->max_advance / 64.0 ));
2892bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  x ppem: %d\n",      metrics->x_ppem ));
2893bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  y ppem: %d\n",      metrics->y_ppem ));
2894bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      }
2895bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#endif
2896bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2897bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      return error;
2898bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
2899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*
2901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * The reason that a driver doesn't have `request_size' defined is
2902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * either that the scaling here suffices or that the supported formats
2903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * are bitmap-only and size matching is not implemented.
2904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
2905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * In the latter case, a simple size matching is done.
2906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     */
2907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_IS_SCALABLE( face ) && FT_HAS_FIXED_SIZES( face ) )
2908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Error  error;
2910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Match_Size( face, req, 0, &strike_index );
2913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
2914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return error;
2915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Select_Size( face, (FT_Int)strike_index );
2917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Request_Metrics( face, req );
2920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Ok;
2922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Set_Char_Size( FT_Face     face,
2929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_F26Dot6  char_width,
2930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_F26Dot6  char_height,
2931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_UInt     horz_resolution,
2932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_UInt     vert_resolution )
2933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Size_RequestRec  req;
2935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !char_width )
2938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      char_width = char_height;
2939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( !char_height )
2940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      char_height = char_width;
2941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !horz_resolution )
2943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      horz_resolution = vert_resolution;
2944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( !vert_resolution )
2945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vert_resolution = horz_resolution;
2946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( char_width  < 1 * 64 )
2948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      char_width  = 1 * 64;
2949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( char_height < 1 * 64 )
2950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      char_height = 1 * 64;
2951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !horz_resolution )
2953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      horz_resolution = vert_resolution = 72;
2954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.type           = FT_SIZE_REQUEST_TYPE_NOMINAL;
2956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.width          = char_width;
2957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.height         = char_height;
2958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.horiResolution = horz_resolution;
2959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.vertResolution = vert_resolution;
2960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Request_Size( face, &req );
2962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Set_Pixel_Sizes( FT_Face  face,
2969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_UInt  pixel_width,
2970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_UInt  pixel_height )
2971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Size_RequestRec  req;
2973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pixel_width == 0 )
2976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pixel_width = pixel_height;
2977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( pixel_height == 0 )
2978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pixel_height = pixel_width;
2979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pixel_width  < 1 )
2981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pixel_width  = 1;
2982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pixel_height < 1 )
2983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pixel_height = 1;
2984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* use `>=' to avoid potential compiler warning on 16bit platforms */
2986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pixel_width  >= 0xFFFFU )
2987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pixel_width  = 0xFFFFU;
2988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pixel_height >= 0xFFFFU )
2989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pixel_height = 0xFFFFU;
2990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.type           = FT_SIZE_REQUEST_TYPE_NOMINAL;
2992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.width          = pixel_width << 6;
2993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.height         = pixel_height << 6;
2994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.horiResolution = 0;
2995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.vertResolution = 0;
2996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Request_Size( face, &req );
2998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Kerning( FT_Face     face,
3005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_UInt     left_glyph,
3006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_UInt     right_glyph,
3007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_UInt     kern_mode,
3008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Vector  *akerning )
3009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error = FT_Err_Ok;
3011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver  driver;
3012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
3015727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
3016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !akerning )
3018727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
3019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    driver = face->driver;
3021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    akerning->x = 0;
3023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    akerning->y = 0;
3024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( driver->clazz->get_kerning )
3026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = driver->clazz->get_kerning( face,
3028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                          left_glyph,
3029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                          right_glyph,
3030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                          akerning );
3031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !error )
3032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( kern_mode != FT_KERNING_UNSCALED )
3034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
3035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          akerning->x = FT_MulFix( akerning->x, face->size->metrics.x_scale );
3036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          akerning->y = FT_MulFix( akerning->y, face->size->metrics.y_scale );
3037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( kern_mode != FT_KERNING_UNFITTED )
3039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
3040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* we scale down kerning values for small ppem values */
3041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* to avoid that rounding makes them too big.         */
3042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* `25' has been determined heuristically.            */
3043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( face->size->metrics.x_ppem < 25 )
3044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              akerning->x = FT_MulDiv( akerning->x,
3045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       face->size->metrics.x_ppem, 25 );
3046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( face->size->metrics.y_ppem < 25 )
3047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              akerning->y = FT_MulDiv( akerning->y,
3048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       face->size->metrics.y_ppem, 25 );
3049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            akerning->x = FT_PIX_ROUND( akerning->x );
3051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            akerning->y = FT_PIX_ROUND( akerning->y );
3052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
3053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
3054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
3058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Track_Kerning( FT_Face    face,
3065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Fixed   point_size,
3066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Int     degree,
3067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Fixed*  akerning )
3068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Service_Kerning  service;
3070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error            error = FT_Err_Ok;
3071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
3074727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
3075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !akerning )
3077727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
3078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FACE_FIND_SERVICE( face, service, KERNING );
3080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !service )
3081727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unimplemented_Feature );
3082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = service->get_track( face,
3084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                point_size,
3085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                degree,
3086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                akerning );
3087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
3089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Select_Charmap( FT_Face      face,
3096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Encoding  encoding )
3097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  cur;
3099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  limit;
3100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
3103727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
3104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( encoding == FT_ENCODING_NONE )
3106727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
3107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* FT_ENCODING_UNICODE is special.  We try to find the `best' Unicode */
3109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* charmap available, i.e., one with UCS-4 characters, if possible.   */
3110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                    */
3111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* This is done by find_unicode_charmap() above, to share code.       */
3112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( encoding == FT_ENCODING_UNICODE )
3113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return find_unicode_charmap( face );
3114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur = face->charmaps;
3116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !cur )
3117727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_CharMap_Handle );
3118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    limit = cur + face->num_charmaps;
3120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; cur < limit; cur++ )
3122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur[0]->encoding == encoding )
3124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3125aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE
3126aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE )
3127aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
3128aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_ERROR(( "FT_Select_Charmap: requested charmap is found (%d), "
3129aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                     "but in too late position to cache\n",
3130aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                     cur - face->charmaps ));
3131aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          continue;
3132aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        }
3133aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
3134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->charmap = cur[0];
3135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return 0;
3136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3139727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_THROW( Invalid_Argument );
3140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Set_Charmap( FT_Face     face,
3147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_CharMap  charmap )
3148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  cur;
3150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  limit;
3151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
3154727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
3155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur = face->charmaps;
3157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !cur )
3158727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_CharMap_Handle );
3159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_Get_CMap_Format( charmap ) == 14 )
3160727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
3161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    limit = cur + face->num_charmaps;
3163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; cur < limit; cur++ )
3165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur[0] == charmap )
3167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3168aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE
3169aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE )
3170aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
3171aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_ERROR(( "FT_Set_Charmap: requested charmap is found (%d), "
3172aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                     "but in too late position to cache\n",
3173aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                     cur - face->charmaps ));
3174aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          continue;
3175aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        }
3176aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
3177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->charmap = cur[0];
3178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return 0;
3179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3181727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_THROW( Invalid_Argument );
3182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Int )
3188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Charmap_Index( FT_CharMap  charmap )
3189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int  i;
3191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3193aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( !charmap || !charmap->face )
3194aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      return -1;
3195aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
3196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0; i < charmap->face->num_charmaps; i++ )
3197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charmap->face->charmaps[i] == charmap )
3198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
3199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( i < charmap->face->num_charmaps );
3201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3202aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE
3203aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( i > FT_MAX_CHARMAP_CACHEABLE )
3204aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    {
3205aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_ERROR(( "FT_Get_Charmap_Index: requested charmap is found (%d), "
3206aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                 "but in too late position to cache\n",
3207aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                 i ));
3208aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      return -i;
3209aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    }
3210aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
3211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return i;
3212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
3216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_cmap_done_internal( FT_CMap  cmap )
3217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CMap_Class  clazz  = cmap->clazz;
3219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face        face   = cmap->charmap.face;
3220727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Memory      memory = FT_FACE_MEMORY( face );
3221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->done )
3224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      clazz->done( cmap );
3225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( cmap );
3227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
3231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_CMap_Done( FT_CMap  cmap )
3232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( cmap )
3234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Face    face   = cmap->charmap.face;
3236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Memory  memory = FT_FACE_MEMORY( face );
3237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Error   error;
3238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int     i, j;
3239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( i = 0; i < face->num_charmaps; i++ )
3242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( (FT_CMap)face->charmaps[i] == cmap )
3244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
3245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_CharMap  last_charmap = face->charmaps[face->num_charmaps - 1];
3246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( FT_RENEW_ARRAY( face->charmaps,
3249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               face->num_charmaps,
3250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               face->num_charmaps - 1 ) )
3251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            return;
3252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* remove it from our list of charmaps */
3254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( j = i + 1; j < face->num_charmaps; j++ )
3255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
3256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( j == face->num_charmaps - 1 )
3257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              face->charmaps[j - 1] = last_charmap;
3258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            else
3259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              face->charmaps[j - 1] = face->charmaps[j];
3260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
3261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          face->num_charmaps--;
3263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( (FT_CMap)face->charmap == cmap )
3265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            face->charmap = NULL;
3266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ft_cmap_done_internal( cmap );
3268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
3270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
3271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
3277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_CMap_New( FT_CMap_Class  clazz,
3278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Pointer     init_data,
3279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_CharMap     charmap,
3280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_CMap       *acmap )
3281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error = FT_Err_Ok;
3283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face    face;
3284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory;
3285aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_CMap    cmap = NULL;
3286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz == NULL || charmap == NULL || charmap->face == NULL )
3289727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
3290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face   = charmap->face;
3292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = FT_FACE_MEMORY( face );
3293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_ALLOC( cmap, clazz->size ) )
3295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cmap->charmap = *charmap;
3297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cmap->clazz   = clazz;
3298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( clazz->init )
3300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = clazz->init( cmap, init_data );
3302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
3303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
3304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* add it to our list of charmaps */
3307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_RENEW_ARRAY( face->charmaps,
3308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           face->num_charmaps,
3309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           face->num_charmaps + 1 ) )
3310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
3311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->charmaps[face->num_charmaps++] = (FT_CharMap)cmap;
3313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
3316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( acmap )
3317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *acmap = cmap;
3318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
3320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
3322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_cmap_done_internal( cmap );
3323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cmap = NULL;
3324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
3325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_UInt )
3331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Char_Index( FT_Face   face,
3332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_ULong  charcode )
3333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  result = 0;
3335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face && face->charmap )
3338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CMap  cmap = FT_CMAP( face->charmap );
3340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3342295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      if ( charcode > 0xFFFFFFFFUL )
3343295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      {
3344295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
3345295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3346295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      }
3347295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode );
3348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3349aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    return result;
3350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_ULong )
3356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_First_Char( FT_Face   face,
3357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_UInt  *agindex )
3358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong  result = 0;
3360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt   gindex = 0;
3361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
33639c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    /* only do something if we have a charmap, and we have glyphs at all */
3364aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( face && face->charmap && face->num_glyphs )
3365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gindex = FT_Get_Char_Index( face, 0 );
3367aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( gindex == 0 || gindex >= (FT_UInt)face->num_glyphs )
3368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = FT_Get_Next_Char( face, 0, &gindex );
3369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3371aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( agindex )
3372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *agindex = gindex;
3373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_ULong )
3381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Next_Char( FT_Face   face,
3382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_ULong  charcode,
3383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_UInt  *agindex )
3384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong  result = 0;
3386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt   gindex = 0;
3387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3389aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( face && face->charmap && face->num_glyphs )
3390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt32  code = (FT_UInt32)charcode;
3392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CMap    cmap = FT_CMAP( face->charmap );
3393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3395ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      do
3396ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      {
3397aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        gindex = cmap->clazz->char_next( cmap, &code );
3398ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
3399aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      } while ( gindex >= (FT_UInt)face->num_glyphs );
3400aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
3401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      result = ( gindex == 0 ) ? 0 : code;
3402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( agindex )
3405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *agindex = gindex;
3406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_UInt )
3414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Face_GetCharVariantIndex( FT_Face   face,
3415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_ULong  charcode,
3416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_ULong  variantSelector )
3417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  result = 0;
3419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face && face->charmap &&
3422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->charmap->encoding == FT_ENCODING_UNICODE )
3423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CharMap  charmap = find_variant_selector_charmap( face );
3425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CMap     ucmap = FT_CMAP( face->charmap );
3426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charmap != NULL )
3429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_CMap  vcmap = FT_CMAP( charmap );
3431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3433295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( charcode > 0xFFFFFFFFUL )
3434295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
3435295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
3436295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3437295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
3438295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( variantSelector > 0xFFFFFFFFUL )
3439295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
3440295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
3441295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
3442295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
3443295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
3444295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        result = vcmap->clazz->char_var_index( vcmap, ucmap,
3445295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                               (FT_UInt32)charcode,
3446295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                               (FT_UInt32)variantSelector );
3447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Int )
3457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Face_GetCharVariantIsDefault( FT_Face   face,
3458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   FT_ULong  charcode,
3459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   FT_ULong  variantSelector )
3460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int  result = -1;
3462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face )
3465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CharMap  charmap = find_variant_selector_charmap( face );
3467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charmap != NULL )
3470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_CMap  vcmap = FT_CMAP( charmap );
3472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3474295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( charcode > 0xFFFFFFFFUL )
3475295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
3476295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
3477295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3478295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
3479295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( variantSelector > 0xFFFFFFFFUL )
3480295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
3481295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
3482295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
3483295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
3484295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
3485295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        result = vcmap->clazz->char_var_default( vcmap,
3486295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                                 (FT_UInt32)charcode,
3487295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                                 (FT_UInt32)variantSelector );
3488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_UInt32* )
3498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Face_GetVariantSelectors( FT_Face  face )
3499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  *result = NULL;
3501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face )
3504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CharMap  charmap = find_variant_selector_charmap( face );
3506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charmap != NULL )
3509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_CMap    vcmap  = FT_CMAP( charmap );
3511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Memory  memory = FT_FACE_MEMORY( face );
3512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = vcmap->clazz->variant_list( vcmap, memory );
3515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_UInt32* )
3525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Face_GetVariantsOfChar( FT_Face   face,
3526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             FT_ULong  charcode )
3527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  *result = NULL;
3529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face )
3532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CharMap  charmap = find_variant_selector_charmap( face );
3534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charmap != NULL )
3537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_CMap    vcmap  = FT_CMAP( charmap );
3539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Memory  memory = FT_FACE_MEMORY( face );
3540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3542295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( charcode > 0xFFFFFFFFUL )
3543295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
3544295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
3545295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3546295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
3547295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
3548295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        result = vcmap->clazz->charvariant_list( vcmap, memory,
3549295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                                 (FT_UInt32)charcode );
3550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_UInt32* )
3559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Face_GetCharsOfVariant( FT_Face   face,
3560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             FT_ULong  variantSelector )
3561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  *result = NULL;
3563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face )
3566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CharMap  charmap = find_variant_selector_charmap( face );
3568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charmap != NULL )
3571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_CMap    vcmap  = FT_CMAP( charmap );
3573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Memory  memory = FT_FACE_MEMORY( face );
3574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3576295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( variantSelector > 0xFFFFFFFFUL )
3577295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
3578295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
3579295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
3580295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
3581295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
3582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = vcmap->clazz->variantchar_list( vcmap, memory,
3583295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                                 (FT_UInt32)variantSelector );
3584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_UInt )
3594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Name_Index( FT_Face     face,
3595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_String*  glyph_name )
3596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  result = 0;
3598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face && FT_HAS_GLYPH_NAMES( face ) )
3601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Service_GlyphDict  service;
3603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FACE_LOOKUP_SERVICE( face,
3606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              service,
3607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              GLYPH_DICT );
3608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( service && service->name_index )
3610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = service->name_index( face, glyph_name );
3611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Glyph_Name( FT_Face     face,
3621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_UInt     glyph_index,
3622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Pointer  buffer,
3623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_UInt     buffer_max )
3624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3625727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error  error = FT_ERR( Invalid_Argument );
3626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* clean up buffer */
3629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( buffer && buffer_max > 0 )
3630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ((FT_Byte*)buffer)[0] = 0;
3631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face                                     &&
3633295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner         (FT_Long)glyph_index <= face->num_glyphs &&
3634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_HAS_GLYPH_NAMES( face )               )
3635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Service_GlyphDict  service;
3637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FACE_LOOKUP_SERVICE( face,
3640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              service,
3641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              GLYPH_DICT );
3642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( service && service->get_name )
3644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = service->get_name( face, glyph_index, buffer, buffer_max );
3645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
3648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( const char* )
3654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Postscript_Name( FT_Face  face )
3655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const char*  result = NULL;
3657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
3660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
3661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !result )
3663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Service_PsFontName  service;
3665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FACE_LOOKUP_SERVICE( face,
3668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              service,
3669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              POSTSCRIPT_FONT_NAME );
3670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( service && service->get_ps_font_name )
3672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = service->get_ps_font_name( face );
3673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
3676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
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( void* )
3683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Sfnt_Table( FT_Face      face,
3684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Sfnt_Tag  tag )
3685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    void*                  table = 0;
3687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Service_SFNT_Table  service;
3688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face && FT_IS_SFNT( face ) )
3691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
3693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( service != NULL )
3694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        table = service->get_table( face, tag );
3695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return table;
3698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in tttables.h */
3702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Load_Sfnt_Table( FT_Face    face,
3705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ULong   tag,
3706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Long    offset,
3707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Byte*   buffer,
3708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ULong*  length )
3709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Service_SFNT_Table  service;
3711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face || !FT_IS_SFNT( face ) )
3714727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
3715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
3717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( service == NULL )
3718727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unimplemented_Feature );
3719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return service->load_table( face, tag, offset, buffer, length );
3721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in tttables.h */
3725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Sfnt_Table_Info( FT_Face    face,
3728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_UInt    table_index,
3729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ULong  *tag,
3730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ULong  *length )
3731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Service_SFNT_Table  service;
3733295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_ULong               offset;
3734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face || !FT_IS_SFNT( face ) )
3737727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
3738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
3740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( service == NULL )
3741727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unimplemented_Feature );
3742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3743295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    return service->table_info( face, table_index, tag, &offset, length );
3744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in tttables.h */
3748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_ULong )
3750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_CMap_Language_ID( FT_CharMap  charmap )
3751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Service_TTCMaps  service;
3753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face             face;
3754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_CMapInfo         cmap_info;
3755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !charmap || !charmap->face )
3758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
3759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face = charmap->face;
3761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FACE_FIND_SERVICE( face, service, TT_CMAP );
3762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( service == NULL )
3763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
3764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( service->get_cmap_info( charmap, &cmap_info ))
3765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
3766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return cmap_info.language;
3768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in tttables.h */
3772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Long )
3774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_CMap_Format( FT_CharMap  charmap )
3775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Service_TTCMaps  service;
3777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face             face;
3778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_CMapInfo         cmap_info;
3779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !charmap || !charmap->face )
3782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return -1;
3783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face = charmap->face;
3785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FACE_FIND_SERVICE( face, service, TT_CMAP );
3786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( service == NULL )
3787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return -1;
3788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( service->get_cmap_info( charmap, &cmap_info ))
3789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return -1;
3790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return cmap_info.format;
3792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftsizes.h */
3796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Activate_Size( FT_Size  size )
3799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face  face;
3801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( size == NULL )
3804727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
3805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face = size->face;
3807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face == NULL || face->driver == NULL )
3808727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
3809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* we don't need anything more complex than that; all size objects */
3811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* are already listed by the face                                  */
3812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->size = size;
3813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Ok;
3815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
3819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
3820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
3821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
3822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
3823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                        R E N D E R E R S                        ****/
3824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
3825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
3826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
3827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
3828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
3829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* lookup a renderer by glyph format in the library's list */
3831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Renderer )
3832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Lookup_Renderer( FT_Library       library,
3833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Glyph_Format  format,
3834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ListNode*     node )
3835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ListNode  cur;
3837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Renderer  result = 0;
3838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
3841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
3842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur = library->renderers.head;
3844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( node )
3846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( *node )
3848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cur = (*node)->next;
3849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *node = 0;
3850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( cur )
3853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Renderer  renderer = FT_RENDERER( cur->data );
3855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( renderer->glyph_format == format )
3858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( node )
3860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *node = cur;
3861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = renderer;
3863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
3864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur = cur->next;
3866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
3869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Renderer
3874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_lookup_glyph_renderer( FT_GlyphSlot  slot )
3875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face      face    = slot->face;
3877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Library   library = FT_FACE_LIBRARY( face );
3878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Renderer  result  = library->cur_renderer;
3879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !result || result->glyph_format != slot->format )
3882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      result = FT_Lookup_Renderer( library, slot->format, 0 );
3883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
3889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_set_current_renderer( FT_Library  library )
3890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Renderer  renderer;
3892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, 0 );
3895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library->cur_renderer = renderer;
3896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
3900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_add_renderer( FT_Module  module )
3901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Library   library = module->library;
3903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory    memory  = library->memory;
3904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error;
3905aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_ListNode  node    = NULL;
3906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( node ) )
3909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
3910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Renderer         render = FT_RENDERER( module );
3913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Renderer_Class*  clazz  = (FT_Renderer_Class*)module->clazz;
3914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      render->clazz        = clazz;
3917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      render->glyph_format = clazz->glyph_format;
3918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* allocate raster object if needed */
3920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
3921aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich           clazz->raster_class->raster_new                )
3922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = clazz->raster_class->raster_new( memory, &render->raster );
3924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
3925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
3926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        render->raster_render = clazz->raster_class->raster_render;
3928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        render->render        = clazz->render_glyph;
3929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* add to list */
3932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      node->data = module;
3933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_List_Add( &library->renderers, node );
3934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_set_current_renderer( library );
3936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
3939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
3940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( node );
3941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
3943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
3944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
3948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_remove_renderer( FT_Module  module )
3949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
39509c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    FT_Library   library;
39519c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    FT_Memory    memory;
3952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ListNode  node;
3953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
39559c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    library = module->library;
39569c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    if ( !library )
39579c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      return;
39589c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
39599c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    memory = library->memory;
39609c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
3961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node = FT_List_Find( &library->renderers, module );
3962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( node )
3963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Renderer  render = FT_RENDERER( module );
3965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* release raster object, if any */
3968aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( render->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
3969aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich           render->raster                                         )
3970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        render->clazz->raster_class->raster_done( render->raster );
3971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* remove from list */
3973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_List_Remove( &library->renderers, node );
3974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( node );
3975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_set_current_renderer( library );
3977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftrender.h */
3982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Renderer )
3984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Renderer( FT_Library       library,
3985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Glyph_Format  format )
3986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `library' delayed to FT_Lookup_Renderer() */
3988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Lookup_Renderer( library, format, 0 );
3990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftrender.h */
3994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Set_Renderer( FT_Library     library,
3997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Renderer    renderer,
3998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_UInt        num_params,
3999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Parameter*  parameters )
4000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ListNode  node;
4002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error = FT_Err_Ok;
4003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
4006727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Library_Handle );
4007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !renderer )
4009727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
4010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node = FT_List_Find( &library->renderers, renderer );
4012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !node )
4013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4014727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Invalid_Argument );
4015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
4016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_List_Up( &library->renderers, node );
4019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( renderer->glyph_format == FT_GLYPH_FORMAT_OUTLINE )
4021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      library->cur_renderer = renderer;
4022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( num_params > 0 )
4024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Renderer_SetModeFunc  set_mode = renderer->clazz->set_mode;
4026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; num_params > 0; num_params-- )
4029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = set_mode( renderer, parameters->tag, parameters->data );
4031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
4032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
4033aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        parameters++;
4034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
4038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
4039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
4043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Render_Glyph_Internal( FT_Library      library,
4044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_GlyphSlot    slot,
4045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_Render_Mode  render_mode )
4046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error = FT_Err_Ok;
4048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Renderer  renderer;
4049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if it is already a bitmap, no need to do anything */
4052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    switch ( slot->format )
4053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_GLYPH_FORMAT_BITMAP:   /* already a bitmap, don't do anything */
4055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
4056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    default:
4058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ListNode  node   = 0;
4060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Bool      update = 0;
4061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* small shortcut for the very common case */
4064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
4065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
4066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          renderer = library->cur_renderer;
4067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          node     = library->renderers.head;
4068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
4069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
4070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          renderer = FT_Lookup_Renderer( library, slot->format, &node );
4071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4072727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_ERR( Unimplemented_Feature );
4073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        while ( renderer )
4074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
4075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          error = renderer->render( renderer, slot, render_mode, NULL );
4076727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          if ( !error                                   ||
4077727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease               FT_ERR_NEQ( error, Cannot_Render_Glyph ) )
4078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            break;
4079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* FT_Err_Cannot_Render_Glyph is returned if the render mode   */
4081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* is unsupported by the current renderer for this glyph image */
4082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* format.                                                     */
4083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* now, look for another renderer that supports the same */
4085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* format.                                               */
4086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          renderer = FT_Lookup_Renderer( library, slot->format, &node );
4087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          update   = 1;
4088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
4089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* if we changed the current renderer for the glyph image format */
4091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* we need to select it as the next current one                  */
4092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !error && update && renderer )
4093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Set_Renderer( library, renderer, 0, 0 );
4094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4097727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef FT_DEBUG_LEVEL_TRACE
4098727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4099727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#undef  FT_COMPONENT
4100727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define FT_COMPONENT  trace_bitmap
4101727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4102727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* we convert to a single bitmap format for computing the checksum */
4103727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
4104727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Bitmap  bitmap;
4105727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Error   err;
4106727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4107727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4108727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Bitmap_New( &bitmap );
4109727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4110727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 );
4111727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( !err )
4112727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
4113727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        MD5_CTX        ctx;
4114727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        unsigned char  md5[16];
4115727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        int            i;
4116727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4117727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4118727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        MD5_Init( &ctx);
4119727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        MD5_Update( &ctx, bitmap.buffer, bitmap.rows * bitmap.pitch );
4120727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        MD5_Final( md5, &ctx );
4121727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4122727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n"
4123727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                    "  ",
4124727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                    bitmap.rows, bitmap.pitch ));
4125727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        for ( i = 0; i < 16; i++ )
4126727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_TRACE3(( "%02X", md5[i] ));
4127727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_TRACE3(( "\n" ));
4128727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
4129727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4130727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Bitmap_Done( library, &bitmap );
4131727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
4132727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4133727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#undef  FT_COMPONENT
4134727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define FT_COMPONENT  trace_objs
4135727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4136727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* FT_DEBUG_LEVEL_TRACE */
4137727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
4139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
4143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
4145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Render_Glyph( FT_GlyphSlot    slot,
4146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Render_Mode  render_mode )
4147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Library  library;
4149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4151aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( !slot || !slot->face )
4152727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
4153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library = FT_FACE_LIBRARY( slot->face );
4155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Render_Glyph_Internal( library, slot, render_mode );
4157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                         M O D U L E S                           ****/
4166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
4175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
4176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Destroy_Module                                                     */
4177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
4178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
4179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Destroys a given module object.  For drivers, this also destroys   */
4180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    all child faces.                                                   */
4181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
4182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <InOut>                                                               */
418341371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier  /*    module :: A handle to the target driver object.                    */
4184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
4185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Note>                                                                */
418641371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier  /*    The driver _must_ be LOCKED!                                       */
4187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
4188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
4189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Destroy_Module( FT_Module  module )
4190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory         memory  = module->memory;
4192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module_Class*  clazz   = module->clazz;
4193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Library        library = module->library;
4194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( library && library->auto_hinter == module )
4197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      library->auto_hinter = 0;
4198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if the module is a renderer */
4200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_RENDERER( module ) )
4201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_remove_renderer( module );
4202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if the module is a font driver, add some steps */
4204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_DRIVER( module ) )
4205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      Destroy_Driver( FT_DRIVER( module ) );
4206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* finalize the module object */
4208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->module_done )
4209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      clazz->module_done( module );
4210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* discard it */
4212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( module );
4213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
4219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Add_Module( FT_Library              library,
4220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const FT_Module_Class*  clazz )
4221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
4223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory;
4224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module  module;
4225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt    nn;
4226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FREETYPE_VER_FIXED  ( ( (FT_Long)FREETYPE_MAJOR << 16 ) | \
4229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                FREETYPE_MINOR                  )
4230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
4232727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Library_Handle );
4233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !clazz )
4235727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
4236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check freetype version */
4238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->module_requires > FREETYPE_VER_FIXED )
4239727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Version );
4240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* look for a module with the same name in the library's table */
4242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( nn = 0; nn < library->num_modules; nn++ )
4243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      module = library->modules[nn];
4245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ft_strcmp( module->clazz->module_name, clazz->module_name ) == 0 )
4246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* this installed module has the same name, compare their versions */
4248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( clazz->module_version <= module->clazz->module_version )
4249727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          return FT_THROW( Lower_Module_Version );
4250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* remove the module from our list, then exit the loop to replace */
4252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* it by our new version..                                        */
4253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Remove_Module( library, module );
4254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
4255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = library->memory;
4259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error  = FT_Err_Ok;
4260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( library->num_modules >= FT_MAX_MODULES )
4262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4263727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Too_Many_Drivers );
4264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
4265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* allocate module object */
4268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( module, clazz->module_size ) )
4269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
4270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* base initialization */
4272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    module->library = library;
4273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    module->memory  = memory;
4274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    module->clazz   = (FT_Module_Class*)clazz;
4275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check whether the module is a renderer - this must be performed */
4277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* before the normal module initialization                         */
4278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_RENDERER( module ) )
4279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* add to the renderers list */
4281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = ft_add_renderer( module );
4282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
4283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
4284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* is the module a auto-hinter? */
4287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_HINTER( module ) )
4288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      library->auto_hinter = module;
4289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if the module is a font driver */
4291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_DRIVER( module ) )
4292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* allocate glyph loader if needed */
4294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Driver  driver = FT_DRIVER( module );
4295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      driver->clazz = (FT_Driver_Class)module->clazz;
4298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_DRIVER_USES_OUTLINES( driver ) )
4299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = FT_GlyphLoader_New( memory, &driver->glyph_loader );
4301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
4302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
4303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->module_init )
4307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = clazz->module_init( module );
4309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
4310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
4311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* add module to the library's table */
4314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library->modules[library->num_modules++] = module;
4315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
4317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
4318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
4320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_DRIVER( module ) )
4321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Driver  driver = FT_DRIVER( module );
4323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_DRIVER_USES_OUTLINES( driver ) )
4326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_GlyphLoader_Done( driver->glyph_loader );
4327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_RENDERER( module ) )
4330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Renderer  renderer = FT_RENDERER( module );
4332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4334ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      if ( renderer->clazz                                          &&
4335ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease           renderer->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
4336aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich           renderer->raster                                         )
4337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        renderer->clazz->raster_class->raster_done( renderer->raster );
4338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( module );
4341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
4342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Module )
4348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Module( FT_Library   library,
4349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const char*  module_name )
4350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module   result = 0;
4352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module*  cur;
4353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module*  limit;
4354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library || !module_name )
4357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return result;
4358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur   = library->modules;
4360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    limit = cur + library->num_modules;
4361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; cur < limit; cur++ )
4363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ft_strcmp( cur[0]->clazz->module_name, module_name ) == 0 )
4364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = cur[0];
4366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
4367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
4370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
4374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( const void* )
4376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Module_Interface( FT_Library   library,
4377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           const char*  mod_name )
4378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module  module;
4380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `library' delayed to FT_Get_Module() */
4383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    module = FT_Get_Module( library, mod_name );
4385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return module ? module->clazz->module_interface : 0;
4387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Pointer )
4391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_module_get_service( FT_Module    module,
4392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         const char*  service_id )
4393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pointer  result = NULL;
4395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4396727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( module )
4398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ASSERT( module->clazz && module->clazz->get_interface );
4400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4401727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      /* first, look for the service in the module */
4402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( module->clazz->get_interface )
4403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = module->clazz->get_interface( module, service_id );
4404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( result == NULL )
4406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4407727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* we didn't find it, look in all other modules then */
4408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Library  library = module->library;
4409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Module*  cur     = library->modules;
4410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Module*  limit   = cur + library->num_modules;
4411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
441241371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier
4413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( ; cur < limit; cur++ )
4414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
4415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( cur[0] != module )
4416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
4417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_ASSERT( cur[0]->clazz );
4418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( cur[0]->clazz->get_interface )
4420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
4421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              result = cur[0]->clazz->get_interface( cur[0], service_id );
4422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( result != NULL )
4423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                break;
4424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
4425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
4426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
4427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
4431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
4437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Remove_Module( FT_Library  library,
4438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Module   module )
4439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* try to find the module from the table, then remove it from there */
4441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
4443727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Library_Handle );
4444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( module )
4446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Module*  cur   = library->modules;
4448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Module*  limit = cur + library->num_modules;
4449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; cur < limit; cur++ )
4452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( cur[0] == module )
4454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
4455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* remove it from the table */
4456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          library->num_modules--;
4457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          limit--;
4458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          while ( cur < limit )
4459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
4460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            cur[0] = cur[1];
4461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            cur++;
4462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
4463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          limit[0] = 0;
4464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* destroy the module */
4466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          Destroy_Module( module );
4467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return FT_Err_Ok;
4469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
4470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4472727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_THROW( Invalid_Driver_Handle );
4473727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
4474727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4475727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
44769c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  static FT_Error
4477727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  ft_property_do( FT_Library        library,
4478727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                  const FT_String*  module_name,
4479727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                  const FT_String*  property_name,
4480727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                  void*             value,
4481727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                  FT_Bool           set )
4482727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
4483727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Module*           cur;
4484727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Module*           limit;
4485727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Module_Interface  interface;
4486727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4487727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Service_Properties  service;
4488727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4489727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef FT_DEBUG_LEVEL_ERROR
4490727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    const FT_String*  set_name  = "FT_Property_Set";
4491727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    const FT_String*  get_name  = "FT_Property_Get";
4492727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    const FT_String*  func_name = set ? set_name : get_name;
4493727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif
4494727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4495727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Bool  missing_func;
4496727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4497727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4498727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( !library )
4499727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Library_Handle );
4500727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4501727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( !module_name || !property_name || !value )
4502727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
4503727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4504727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cur   = library->modules;
4505727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    limit = cur + library->num_modules;
4506727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4507727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* search module */
4508727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    for ( ; cur < limit; cur++ )
4509727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( !ft_strcmp( cur[0]->clazz->module_name, module_name ) )
4510727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        break;
4511727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4512727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( cur == limit )
4513727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
4514727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_ERROR(( "%s: can't find module `%s'\n",
4515727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                 func_name, module_name ));
4516727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Missing_Module );
4517727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
4518727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4519727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* check whether we have a service interface */
4520727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( !cur[0]->clazz->get_interface )
4521727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
4522727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_ERROR(( "%s: module `%s' doesn't support properties\n",
4523727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                 func_name, module_name ));
4524727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unimplemented_Feature );
4525727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
4526727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4527727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* search property service */
4528727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    interface = cur[0]->clazz->get_interface( cur[0],
4529727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                              FT_SERVICE_ID_PROPERTIES );
4530727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( !interface )
4531727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
4532727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_ERROR(( "%s: module `%s' doesn't support properties\n",
4533727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                 func_name, module_name ));
4534727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unimplemented_Feature );
4535727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
4536727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4537727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    service = (FT_Service_Properties)interface;
4538727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4539727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( set )
4540ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      missing_func = (FT_Bool)( !service->set_property );
4541727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    else
4542ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      missing_func = (FT_Bool)( !service->get_property );
4543727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4544727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( missing_func )
4545727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
4546727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_ERROR(( "%s: property service of module `%s' is broken\n",
4547727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                 func_name, module_name ));
4548727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unimplemented_Feature );
4549727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
4550727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4551727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return set ? service->set_property( cur[0], property_name, value )
4552727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease               : service->get_property( cur[0], property_name, value );
4553727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
4554727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4555727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4556727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* documentation is in ftmodapi.h */
4557727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4558727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_EXPORT_DEF( FT_Error )
4559727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_Property_Set( FT_Library        library,
4560727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   const FT_String*  module_name,
4561727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   const FT_String*  property_name,
4562727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   const void*       value )
4563727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
4564727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return ft_property_do( library,
4565727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                           module_name,
4566727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                           property_name,
4567727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                           (void*)value,
4568727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                           TRUE );
4569727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
4570727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4571727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4572727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* documentation is in ftmodapi.h */
4573727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4574727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_EXPORT_DEF( FT_Error )
4575727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_Property_Get( FT_Library        library,
4576727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   const FT_String*  module_name,
4577727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   const FT_String*  property_name,
4578727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   void*             value )
4579727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
4580727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return ft_property_do( library,
4581727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                           module_name,
4582727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                           property_name,
4583727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                           value,
4584727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                           FALSE );
4585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                         L I B R A R Y                           ****/
4594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
4604aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  FT_Reference_Library( FT_Library  library )
4605aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  {
4606aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    library->refcount++;
4607aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4608aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    return FT_Err_Ok;
4609aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  }
4610aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4611aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4612aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  /* documentation is in ftmodapi.h */
4613aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4614aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  FT_EXPORT_DEF( FT_Error )
4615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_New_Library( FT_Memory    memory,
4616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Library  *alibrary )
4617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4618aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Library  library = NULL;
4619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error    error;
4620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !memory )
4623727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
4624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_DEBUG_LEVEL_ERROR
4626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* init debugging support */
4627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_debug_init();
4628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
4629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* first of all, allocate the library object */
4631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( library ) )
4632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
4633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library->memory = memory;
4635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4636295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifdef FT_CONFIG_OPTION_PIC
4637295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* initialize position independent code containers */
4638295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    error = ft_pic_container_init( library );
4639295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( error )
4640295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      goto Fail;
4641295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
4642295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
4643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* allocate the render pool */
4644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library->raster_pool_size = FT_RENDER_POOL_SIZE;
4645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if FT_RENDER_POOL_SIZE > 0
4646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )
4647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
4648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
4649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4650295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    library->version_major = FREETYPE_MAJOR;
4651295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    library->version_minor = FREETYPE_MINOR;
4652295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    library->version_patch = FREETYPE_PATCH;
4653295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
4654aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    library->refcount = 1;
4655aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* That's ok now */
4657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *alibrary = library;
4658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Ok;
4660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
4662295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifdef FT_CONFIG_OPTION_PIC
4663295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    ft_pic_container_destroy( library );
4664295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
4665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( library );
4666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
4667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
4671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
4673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Library_Version( FT_Library   library,
4674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Int      *amajor,
4675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Int      *aminor,
4676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Int      *apatch )
4677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int  major = 0;
4679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int  minor = 0;
4680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int  patch = 0;
4681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( library )
4684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      major = library->version_major;
4686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      minor = library->version_minor;
4687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      patch = library->version_patch;
4688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( amajor )
4691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *amajor = major;
4692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( aminor )
4694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *aminor = minor;
4695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( apatch )
4697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *apatch = patch;
4698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
4704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Done_Library( FT_Library  library )
4705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory;
4707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
4710727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Library_Handle );
4711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4712aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    library->refcount--;
4713aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( library->refcount > 0 )
4714aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      goto Exit;
4715aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = library->memory;
4717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4718aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    /*
4719aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     * Close all faces in the library.  If we don't do this, we can have
4720aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     * some subtle memory leaks.
4721aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     *
4722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * Example:
4723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
4724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  - the cff font driver uses the pshinter module in cff_size_done
4725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  - if the pshinter module is destroyed before the cff font driver,
4726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *    opened FT_Face objects managed by the driver are not properly
4727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *    destroyed, resulting in a memory leak
4728aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     *
4729aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     * Some faces are dependent on other faces, like Type42 faces that
4730aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     * depend on TrueType faces synthesized internally.
4731aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     *
4732aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     * The order of drivers should be specified in driver_name[].
4733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     */
4734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4735aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_UInt      m, n;
4736aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      const char*  driver_name[] = { "type42", NULL };
4737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4739aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      for ( m = 0;
4740aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            m < sizeof ( driver_name ) / sizeof ( driver_name[0] );
4741aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            m++ )
4742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4743aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        for ( n = 0; n < library->num_modules; n++ )
4744aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
4745aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_Module    module      = library->modules[n];
4746aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          const char*  module_name = module->clazz->module_name;
4747aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_List      faces;
4748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4750aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          if ( driver_name[m]                                &&
4751aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich               ft_strcmp( module_name, driver_name[m] ) != 0 )
4752aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            continue;
4753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4754aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          if ( ( module->clazz->module_flags & FT_MODULE_FONT_DRIVER ) == 0 )
4755aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            continue;
4756aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4757aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_TRACE7(( "FT_Done_Library: close faces for %s\n", module_name ));
4758aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4759aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          faces = &FT_DRIVER( module )->faces_list;
4760aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          while ( faces->head )
4761aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          {
4762aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            FT_Done_Face( FT_FACE( faces->head->data ) );
4763aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            if ( faces->head )
4764aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich              FT_TRACE0(( "FT_Done_Library: failed to free some faces\n" ));
4765aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          }
476677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        }
4767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Close all other modules in the library */
4771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 1
4772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* XXX Modules are removed in the reversed order so that  */
4773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* type42 module is removed before truetype module.  This */
4774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* avoids double free in some occasions.  It is a hack.   */
4775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( library->num_modules > 0 )
4776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Remove_Module( library,
4777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        library->modules[library->num_modules - 1] );
4778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
4779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt  n;
4781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( n = 0; n < library->num_modules; n++ )
4784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Module  module = library->modules[n];
4786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( module )
4789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
4790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          Destroy_Module( module );
4791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          library->modules[n] = 0;
4792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
4793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
4796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Destroy raster objects */
4798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( library->raster_pool );
4799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library->raster_pool_size = 0;
4800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4801295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifdef FT_CONFIG_OPTION_PIC
4802295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* Destroy pic container contents */
4803295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    ft_pic_container_destroy( library );
4804295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
4805295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
4806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( library );
4807aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4808aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  Exit:
4809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Ok;
4810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
4816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Set_Debug_Hook( FT_Library         library,
4817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_UInt            hook_index,
4818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_DebugHook_Func  debug_hook )
4819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( library && debug_hook &&
4821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         hook_index <
4822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) )
4823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      library->debug_hooks[hook_index] = debug_hook;
4824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_TrueTypeEngineType )
4830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_TrueType_Engine_Type( FT_Library  library )
4831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TrueTypeEngineType  result = FT_TRUETYPE_ENGINE_TYPE_NONE;
4833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( library )
4836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Module  module = FT_Get_Module( library, "truetype" );
4838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( module )
4841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Service_TrueTypeEngine  service;
4843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        service = (FT_Service_TrueTypeEngine)
4846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    ft_module_get_service( module,
4847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           FT_SERVICE_ID_TRUETYPE_ENGINE );
4848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( service )
4849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result = service->engine_type;
4850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
4854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4857aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  /* documentation is in freetype.h */
4858aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
4860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_SubGlyph_Info( FT_GlyphSlot  glyph,
4861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_UInt       sub_index,
4862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Int       *p_index,
4863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_UInt      *p_flags,
4864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Int       *p_arg1,
4865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Int       *p_arg2,
4866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Matrix    *p_transform )
4867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4868727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error  error = FT_ERR( Invalid_Argument );
4869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4871aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( glyph                                      &&
4872aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         glyph->subglyphs                           &&
4873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         glyph->format == FT_GLYPH_FORMAT_COMPOSITE &&
4874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         sub_index < glyph->num_subglyphs           )
4875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_SubGlyph  subg = glyph->subglyphs + sub_index;
4877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *p_index     = subg->index;
4880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *p_flags     = subg->flags;
4881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *p_arg1      = subg->arg1;
4882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *p_arg2      = subg->arg2;
4883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *p_transform = subg->transform;
48849c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
48859c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      error = FT_Err_Ok;
4886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
4889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
4893