ftobjs.c revision 727dee178a392d20eb050d0c446f2fcc29058fa1
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/*                                                                         */
7727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  Copyright 1996-2013 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#define free  md5_free /* suppress a shadow warning */
60727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "md5.c"
61727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#undef free
62727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
63727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#if defined( _MSC_VER )
64727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#pragma warning( pop )
65727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif
66727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
67727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* FT_DEBUG_LEVEL_TRACE */
68727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
69727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define GRID_FIT_METRICS
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
7277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Pointer )
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_service_list_lookup( FT_ServiceDesc  service_descriptors,
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          const char*     service_id )
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pointer      result = NULL;
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ServiceDesc  desc   = service_descriptors;
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( desc && service_id )
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; desc->serv_id != NULL; desc++ )
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ft_strcmp( desc->serv_id, service_id ) == 0 )
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result = (FT_Pointer)desc->serv_data;
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_validator_init( FT_Validator        valid,
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     const FT_Byte*      base,
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     const FT_Byte*      limit,
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_ValidationLevel  level )
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    valid->base  = base;
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    valid->limit = limit;
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    valid->level = level;
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    valid->error = FT_Err_Ok;
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Int )
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_validator_run( FT_Validator  valid )
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* This function doesn't work!  None should call it. */
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( valid );
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return -1;
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_validator_error( FT_Validator  valid,
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Error      error )
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* since the cast below also disables the compiler's */
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* type check, we introduce a dummy variable, which  */
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* will be optimized away                            */
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    volatile ft_jmp_buf* jump_buffer = &valid->jump_buffer;
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    valid->error = error;
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* throw away volatileness; use `jump_buffer' or the  */
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* compiler may warn about an unused local variable   */
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_longjmp( *(ft_jmp_buf*) jump_buffer, 1 );
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  /****                                                                 ****/
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                           S T R E A M                           ****/
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
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* create a new input stream from an FT_Open_Args structure */
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                          */
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_New( FT_Library           library,
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const FT_Open_Args*  args,
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Stream           *astream )
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory;
160aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_Stream  stream = NULL;
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
16377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    *astream = 0;
16477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
166727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Library_Handle );
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !args )
169727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
171aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    memory = library->memory;
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( stream ) )
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->memory = memory;
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( args->flags & FT_OPEN_MEMORY )
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* create a memory-based stream */
181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_OpenMemory( stream,
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            (const FT_Byte*)args->memory_base,
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            args->memory_size );
184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
185aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
186aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifndef FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT
187aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( args->flags & FT_OPEN_PATHNAME )
189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* create a normal system stream */
191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Stream_Open( stream, args->pathname );
192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->pathname.pointer = args->pathname;
193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( ( args->flags & FT_OPEN_STREAM ) && args->stream )
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* use an existing, user-provided stream */
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* in this case, we do not need to allocate a new stream object */
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* since the caller is responsible for closing it himself       */
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( stream );
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream = args->stream;
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
203aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
204aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif
205aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
207727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Invalid_Argument );
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( stream );
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      stream->memory = memory;  /* just to be certain */
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *astream = stream;
215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Stream_Free( FT_Stream  stream,
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Int     external )
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( stream )
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Memory  memory = stream->memory;
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_Close( stream );
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !external )
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FREE( stream );
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
23877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /*************************************************************************/
23977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /*                                                                       */
24077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
24177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
24277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* messages during execution.                                            */
24377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /*                                                                       */
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_objs
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  /****                                                                 ****/
252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****               FACE, SIZE & GLYPH SLOT OBJECTS                   ****/
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
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_init( FT_GlyphSlot  slot )
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
264aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Driver         driver   = slot->face->driver;
265aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Driver_Class   clazz    = driver->clazz;
266aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Memory         memory   = driver->root.memory;
267aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Error          error    = FT_Err_Ok;
268aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Slot_Internal  internal = NULL;
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->library = driver->root.library;
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( internal ) )
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->internal = internal;
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_DRIVER_USES_OUTLINES( driver ) )
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_GlyphLoader_New( memory, &internal->loader );
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error && clazz->init_slot )
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = clazz->init_slot( slot );
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_free_bitmap( FT_GlyphSlot  slot )
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
29277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( slot->internal && ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) )
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Memory  memory = FT_FACE_MEMORY( slot->face );
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( slot->bitmap.buffer );
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* assume that the bitmap buffer was stolen or not */
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* allocated from the heap                         */
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->bitmap.buffer = NULL;
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_set_bitmap( FT_GlyphSlot  slot,
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_Byte*      buffer )
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_glyphslot_free_bitmap( slot );
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap.buffer = buffer;
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( (slot->internal->flags & FT_GLYPH_OWN_BITMAP) == 0 );
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_alloc_bitmap( FT_GlyphSlot  slot,
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             FT_ULong      size )
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = FT_FACE_MEMORY( slot->face );
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( slot->bitmap.buffer );
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (void)FT_ALLOC( slot->bitmap.buffer, size );
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_clear( FT_GlyphSlot  slot )
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* free bitmap if needed */
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_glyphslot_free_bitmap( slot );
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* clear all public fields in the glyph slot */
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ZERO( &slot->metrics );
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ZERO( &slot->outline );
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap.width      = 0;
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap.rows       = 0;
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap.pitch      = 0;
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap.pixel_mode = 0;
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* `slot->bitmap.buffer' has been handled by ft_glyphslot_free_bitmap */
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap_left   = 0;
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->bitmap_top    = 0;
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->num_subglyphs = 0;
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->subglyphs     = 0;
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->control_data  = 0;
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->control_len   = 0;
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->other         = 0;
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->format        = FT_GLYPH_FORMAT_NONE;
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->linearHoriAdvance = 0;
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->linearVertAdvance = 0;
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->lsb_delta         = 0;
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot->rsb_delta         = 0;
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_done( FT_GlyphSlot  slot )
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver        driver = slot->face->driver;
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz  = driver->clazz;
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory        memory = driver->root.memory;
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->done_slot )
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      clazz->done_slot( slot );
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* free bitmap buffer if needed */
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_glyphslot_free_bitmap( slot );
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
385295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* slot->internal might be NULL in out-of-memory situations */
386295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( slot->internal )
387295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    {
388aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* free glyph loader */
389aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( FT_DRIVER_USES_OUTLINES( driver ) )
390aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      {
391aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        FT_GlyphLoader_Done( slot->internal->loader );
392aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        slot->internal->loader = 0;
393aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      }
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
395aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_FREE( slot->internal );
396295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    }
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_New_GlyphSlot( FT_Face        face,
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_GlyphSlot  *aslot )
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error         error;
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver        driver;
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz;
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory        memory;
410aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_GlyphSlot     slot = NULL;
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face || !face->driver )
414727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    driver = face->driver;
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clazz  = driver->clazz;
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = driver->root.memory;
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE4(( "FT_New_GlyphSlot: Creating new slot object\n" ));
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_ALLOC( slot, clazz->slot_object_size ) )
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->face = face;
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = ft_glyphslot_init( slot );
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ft_glyphslot_done( slot );
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FREE( slot );
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->next  = face->glyph;
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->glyph = slot;
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( aslot )
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        *aslot = slot;
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( aslot )
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *aslot = 0;
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE4(( "FT_New_GlyphSlot: Return %d\n", error ));
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Done_GlyphSlot( FT_GlyphSlot  slot )
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( slot )
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Driver     driver = slot->face->driver;
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Memory     memory = driver->root.memory;
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphSlot  prev;
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphSlot  cur;
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Remove slot from its parent face's list */
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      prev = NULL;
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur  = slot->face->glyph;
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( cur )
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( cur == slot )
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( !prev )
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            slot->face->glyph = cur->next;
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          else
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            prev->next = cur->next;
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
47541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier          /* finalize client-specific data */
47641371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier          if ( slot->generic.finalizer )
47741371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier            slot->generic.finalizer( slot );
47841371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ft_glyphslot_done( slot );
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_FREE( slot );
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        prev = cur;
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cur  = cur->next;
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Set_Transform( FT_Face     face,
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Matrix*  matrix,
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Vector*  delta )
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face_Internal  internal;
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    internal = face->internal;
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    internal->transform_flags = 0;
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !matrix )
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.xx = 0x10000L;
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.xy = 0;
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.yx = 0;
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.yy = 0x10000L;
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      matrix = &internal->transform_matrix;
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix = *matrix;
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* set transform_flags bit flag 0 if `matrix' isn't the identity */
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ( matrix->xy | matrix->yx ) ||
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         matrix->xx != 0x10000L      ||
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         matrix->yy != 0x10000L      )
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_flags |= 1;
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !delta )
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_delta.x = 0;
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_delta.y = 0;
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta = &internal->transform_delta;
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_delta = *delta;
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* set transform_flags bit flag 1 if `delta' isn't the null vector */
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( delta->x | delta->y )
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_flags |= 2;
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Renderer
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_lookup_glyph_renderer( FT_GlyphSlot  slot );
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef GRID_FIT_METRICS
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_glyphslot_grid_fit_metrics( FT_GlyphSlot  slot,
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 FT_Bool       vertical )
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Glyph_Metrics*  metrics = &slot->metrics;
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pos             right, bottom;
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( vertical )
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX );
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY );
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      right  = FT_PIX_CEIL( metrics->vertBearingX + metrics->width );
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bottom = FT_PIX_CEIL( metrics->vertBearingY + metrics->height );
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->width  = right - metrics->vertBearingX;
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->height = bottom - metrics->vertBearingY;
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->vertBearingX = FT_PIX_FLOOR( metrics->vertBearingX );
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->vertBearingY = FT_PIX_FLOOR( metrics->vertBearingY );
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      right  = FT_PIX_CEIL ( metrics->horiBearingX + metrics->width );
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bottom = FT_PIX_FLOOR( metrics->horiBearingY - metrics->height );
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->horiBearingX = FT_PIX_FLOOR( metrics->horiBearingX );
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->horiBearingY = FT_PIX_CEIL ( metrics->horiBearingY );
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->width  = right - metrics->horiBearingX;
578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->height = metrics->horiBearingY - bottom;
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->horiAdvance = FT_PIX_ROUND( metrics->horiAdvance );
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->vertAdvance = FT_PIX_ROUND( metrics->vertAdvance );
583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* GRID_FIT_METRICS */
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Load_Glyph( FT_Face   face,
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_UInt   glyph_index,
592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Int32  load_flags )
593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error      error;
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver     driver;
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphSlot  slot;
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Library    library;
59877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Bool       autohint = FALSE;
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module     hinter;
600aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    TT_Face       ttface = (TT_Face)face;
601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face || !face->size || !face->glyph )
604727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* The validity test for `glyph_index' is performed by the */
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* font drivers.                                           */
608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    slot = face->glyph;
610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_glyphslot_clear( slot );
611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    driver  = face->driver;
613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library = driver->root.library;
614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hinter  = library->auto_hinter;
615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* resolve load flags dependencies */
617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( load_flags & FT_LOAD_NO_RECURSE )
619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      load_flags |= FT_LOAD_NO_SCALE         |
620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_LOAD_IGNORE_TRANSFORM;
621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( load_flags & FT_LOAD_NO_SCALE )
623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      load_flags |= FT_LOAD_NO_HINTING |
625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_LOAD_NO_BITMAP;
626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      load_flags &= ~FT_LOAD_RENDER;
628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*
631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * Determine whether we need to auto-hint or not.
632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * The general rules are:
633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
634295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     * - Do only auto-hinting if we have a hinter module, a scalable font
635295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     *   format dealing with outlines, and no transforms except simple
636295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     *   slants and/or rotations by integer multiples of 90 degrees.
637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
638295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't
639295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     *   have a native font hinter.
640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
641aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner     * - Otherwise, auto-hint for LIGHT hinting mode or if there isn't
642aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner     *   any hinting bytecode in the TrueType/OpenType font.
643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
644295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     * - Exception: The font is `tricky' and requires the native hinter to
645295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner     *   load properly.
646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     */
647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
648aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( hinter                                           &&
649aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         !( load_flags & FT_LOAD_NO_HINTING )             &&
650aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         !( load_flags & FT_LOAD_NO_AUTOHINT )            &&
651aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         FT_DRIVER_IS_SCALABLE( driver )                  &&
652aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         FT_DRIVER_USES_OUTLINES( driver )                &&
653aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         !FT_IS_TRICKY( face )                            &&
654bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly         ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM )    ||
655bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly           ( face->internal->transform_matrix.yx == 0 &&
656295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner             face->internal->transform_matrix.xx != 0 ) ||
657295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner           ( face->internal->transform_matrix.xx == 0 &&
658295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner             face->internal->transform_matrix.yx != 0 ) ) )
65977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    {
66077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      if ( ( load_flags & FT_LOAD_FORCE_AUTOHINT ) ||
66177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner           !FT_DRIVER_HAS_HINTER( driver )         )
66277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        autohint = TRUE;
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Render_Mode  mode = FT_LOAD_TARGET_MODE( load_flags );
666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
668aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        /* the check for `num_locations' assures that we actually    */
669aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        /* test for instructions in a TTF and not in a CFF-based OTF */
670aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        if ( mode == FT_RENDER_MODE_LIGHT                       ||
671aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner             face->internal->ignore_unpatented_hinter           ||
672aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner             ( FT_IS_SFNT( face )                             &&
673aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner               ttface->num_locations                          &&
674aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner               ttface->max_profile.maxSizeOfInstructions == 0 ) )
67577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          autohint = TRUE;
676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( autohint )
680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
681727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_AutoHinter_Interface  hinting;
682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* try to load embedded bitmaps first if available            */
685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*                                                            */
686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* XXX: This is really a temporary hack that should disappear */
687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*      promptly with FreeType 2.1!                           */
688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*                                                            */
689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_HAS_FIXED_SIZES( face )             &&
690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = driver->clazz->load_glyph( slot, face->size,
693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           glyph_index,
694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           load_flags | FT_LOAD_SBITS_ONLY );
695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !error && slot->format == FT_GLYPH_FORMAT_BITMAP )
697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Load_Ok;
698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Face_Internal  internal        = face->internal;
702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int            transform_flags = internal->transform_flags;
703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* since the auto-hinter calls FT_Load_Glyph by itself, */
706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* make sure that glyphs aren't transformed             */
707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        internal->transform_flags = 0;
708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* load auto-hinted outline */
710727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        hinting = (FT_AutoHinter_Interface)hinter->clazz->module_interface;
711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error   = hinting->load_glyph( (FT_AutoHinter)hinter,
713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       slot, face->size,
714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       glyph_index, load_flags );
715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        internal->transform_flags = transform_flags;
717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = driver->clazz->load_glyph( slot,
722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                         face->size,
723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                         glyph_index,
724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                         load_flags );
725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* check that the loaded outline is correct */
731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = FT_Outline_Check( &slot->outline );
732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef GRID_FIT_METRICS
736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !( load_flags & FT_LOAD_NO_HINTING ) )
737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ft_glyphslot_grid_fit_metrics( slot,
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              FT_BOOL( load_flags & FT_LOAD_VERTICAL_LAYOUT ) );
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Load_Ok:
744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* compute the advance */
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->advance.x = 0;
748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->advance.y = slot->metrics.vertAdvance;
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->advance.x = slot->metrics.horiAdvance;
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->advance.y = 0;
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* compute the linear advance in 16.16 pixels */
757aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( ( load_flags & FT_LOAD_LINEAR_DESIGN ) == 0 &&
758aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         ( FT_IS_SCALABLE( face ) )                  )
759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Size_Metrics*  metrics = &face->size->metrics;
761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* it's tricky! */
764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->linearHoriAdvance = FT_MulDiv( slot->linearHoriAdvance,
765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           metrics->x_scale, 64 );
766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->linearVertAdvance = FT_MulDiv( slot->linearVertAdvance,
768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           metrics->y_scale, 64 );
769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ( load_flags & FT_LOAD_IGNORE_TRANSFORM ) == 0 )
772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Face_Internal  internal = face->internal;
774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* now, transform the glyph image if needed */
777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( internal->transform_flags )
778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* get renderer */
780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Renderer  renderer = ft_lookup_glyph_renderer( slot );
781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( renderer )
784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          error = renderer->clazz->transform_glyph(
785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                     renderer, slot,
786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                     &internal->transform_matrix,
787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                     &internal->transform_delta );
788295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        else if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
789295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
790295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          /* apply `standard' transformation if no renderer is available */
791bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          if ( internal->transform_flags & 1 )
792295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            FT_Outline_Transform( &slot->outline,
793295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                  &internal->transform_matrix );
794295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
795bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly          if ( internal->transform_flags & 2 )
796295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            FT_Outline_Translate( &slot->outline,
797295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                  internal->transform_delta.x,
798295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                  internal->transform_delta.y );
799295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
800295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* transform advance */
802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Vector_Transform( &slot->advance, &internal->transform_matrix );
803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
806295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_TRACE5(( "  x advance: %d\n" , slot->advance.x ));
807295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_TRACE5(( "  y advance: %d\n" , slot->advance.y ));
808295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
809295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_TRACE5(( "  linear x advance: %d\n" , slot->linearHoriAdvance ));
810295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_TRACE5(( "  linear y advance: %d\n" , slot->linearVertAdvance ));
811295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* do we need to render the image now? */
813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error                                    &&
814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         slot->format != FT_GLYPH_FORMAT_BITMAP    &&
815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         slot->format != FT_GLYPH_FORMAT_COMPOSITE &&
816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         load_flags & FT_LOAD_RENDER )
817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Render_Mode  mode = FT_LOAD_TARGET_MODE( load_flags );
819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( mode == FT_RENDER_MODE_NORMAL      &&
822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           (load_flags & FT_LOAD_MONOCHROME ) )
823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        mode = FT_RENDER_MODE_MONO;
824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Render_Glyph( slot, mode );
826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Load_Char( FT_Face   face,
837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_ULong  char_code,
838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Int32  load_flags )
839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  glyph_index;
841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
844727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    glyph_index = (FT_UInt)char_code;
847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->charmap )
848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph_index = FT_Get_Char_Index( face, char_code );
849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Load_Glyph( face, glyph_index, load_flags );
851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* destructor for sizes list */
855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  destroy_size( FT_Memory  memory,
857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Size    size,
858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Driver  driver )
859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* finalize client-specific data */
861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( size->generic.finalizer )
862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      size->generic.finalizer( size );
863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* finalize format-specific stuff */
865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( driver->clazz->done_size )
866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      driver->clazz->done_size( size );
867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( size->internal );
869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( size );
870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_cmap_done_internal( FT_CMap  cmap );
875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  destroy_charmaps( FT_Face    face,
879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Memory  memory )
880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int  n;
882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( n = 0; n < face->num_charmaps; n++ )
888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CMap  cmap = FT_CMAP( face->charmaps[n] );
890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_cmap_done_internal( cmap );
893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->charmaps[n] = NULL;
895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( face->charmaps );
898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->num_charmaps = 0;
899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* destructor for faces list */
903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  destroy_face( FT_Memory  memory,
905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Face    face,
906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Driver  driver )
907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz = driver->clazz;
909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* discard auto-hinting data */
912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->autohint.finalizer )
913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->autohint.finalizer( face->autohint.data );
914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Discard glyph slots for this face.                           */
916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Beware!  FT_Done_GlyphSlot() changes the field `face->glyph' */
917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( face->glyph )
918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Done_GlyphSlot( face->glyph );
919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* discard all sizes for this face */
921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_List_Finalize( &face->sizes_list,
922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      (FT_List_Destructor)destroy_size,
923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      memory,
924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      driver );
925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->size = 0;
926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* now discard client data */
928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->generic.finalizer )
929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->generic.finalizer( face );
930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* discard charmaps */
932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    destroy_charmaps( face, memory );
933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* finalize format-specific stuff */
935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->done_face )
936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      clazz->done_face( face );
937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* close the stream for this face if needed */
939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream_Free(
940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->stream,
941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ( face->face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->stream = 0;
944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* get rid of it */
946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->internal )
947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( face->internal );
949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( face );
951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Destroy_Driver( FT_Driver  driver )
956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_List_Finalize( &driver->faces_list,
958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      (FT_List_Destructor)destroy_face,
959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      driver->root.memory,
960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      driver );
961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check whether we need to drop the driver's glyph loader */
963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_DRIVER_USES_OUTLINES( driver ) )
964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphLoader_Done( driver->glyph_loader );
965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    find_unicode_charmap                                               */
972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    This function finds a Unicode charmap, if there is one.            */
975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    And if there is more than one, it tries to favour the more         */
976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    extensive one, i.e., one that supports UCS-4 against those which   */
977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    are limited to the BMP (said UCS-2 encoding.)                      */
978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    This function is called from open_face() (just below), and also    */
980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    from FT_Select_Charmap( ..., FT_ENCODING_UNICODE ).                */
981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  find_unicode_charmap( FT_Face  face )
984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  first;
986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  cur;
987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* caller should have already checked that `face' is valid */
990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( face );
991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    first = face->charmaps;
993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !first )
995727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_CharMap_Handle );
996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*
998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  The original TrueType specification(s) only specified charmap
999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  formats that are capable of mapping 8 or 16 bit character codes to
1000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  glyph indices.
1001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
1002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  However, recent updates to the Apple and OpenType specifications
1003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  introduced new formats that are capable of mapping 32-bit character
1004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  codes as well.  And these are already used on some fonts, mainly to
1005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  map non-BMP Asian ideographs as defined in Unicode.
1006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
1007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  For compatibility purposes, these fonts generally come with
1008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  *several* Unicode charmaps:
1009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
1010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *   - One of them in the "old" 16-bit format, that cannot access
1011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *     all glyphs in the font.
1012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
1013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *   - Another one in the "new" 32-bit format, that can access all
1014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *     the glyphs.
1015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
1016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  This function has been written to always favor a 32-bit charmap
1017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  when found.  Otherwise, a 16-bit one is returned when found.
1018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     */
1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Since the `interesting' table, with IDs (3,10), is normally the */
1021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* last one, we loop backwards.  This loses with type1 fonts with  */
1022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* non-BMP characters (<.0001%), this wins with .ttf with non-BMP  */
1023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* chars (.01% ?), and this is the same about 99.99% of the time!  */
1024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur = first + face->num_charmaps;  /* points after the last one */
1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; --cur >= first; )
1028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur[0]->encoding == FT_ENCODING_UNICODE )
1030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* XXX If some new encodings to represent UCS-4 are added, */
1032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /*     they should be added here.                          */
1033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ( cur[0]->platform_id == TT_PLATFORM_MICROSOFT &&
1034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               cur[0]->encoding_id == TT_MS_ID_UCS_4        )     ||
1035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE &&
1036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               cur[0]->encoding_id == TT_APPLE_ID_UNICODE_32    ) )
1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1038aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE
1039aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )
1040aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          {
1041aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            FT_ERROR(( "find_unicode_charmap: UCS-4 cmap is found "
1042aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                       "at too late position (%d)\n", cur - first ));
1043aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            continue;
1044aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          }
1045aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
1046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          face->charmap = cur[0];
1047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return FT_Err_Ok;
1048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* We do not have any UCS-4 charmap.                */
1053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Do the loop again and search for UCS-2 charmaps. */
1054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur = first + face->num_charmaps;
1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; --cur >= first; )
1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur[0]->encoding == FT_ENCODING_UNICODE )
1059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1060aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE
1061aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )
1062aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
1063aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_ERROR(( "find_unicode_charmap: UCS-2 cmap is found "
1064aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                     "at too late position (%d)\n", cur - first ));
1065aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          continue;
1066aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        }
1067aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
1068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->charmap = cur[0];
1069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return FT_Err_Ok;
1070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1073727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_THROW( Invalid_CharMap_Handle );
1074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
1080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    find_variant_selector_charmap                                      */
1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
1083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    This function finds the variant selector charmap, if there is one. */
1084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    There can only be one (platform=0, specific=5, format=14).         */
1085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_CharMap
1087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  find_variant_selector_charmap( FT_Face  face )
1088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  first;
1090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  end;
1091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  cur;
1092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* caller should have already checked that `face' is valid */
1095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( face );
1096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    first = face->charmaps;
1098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !first )
1100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return NULL;
1101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    end = first + face->num_charmaps;  /* points after the last one */
1103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( cur = first; cur < end; ++cur )
1105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur[0]->platform_id == TT_PLATFORM_APPLE_UNICODE    &&
1107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           cur[0]->encoding_id == TT_APPLE_ID_VARIANT_SELECTOR &&
1108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           FT_Get_CMap_Format( cur[0] ) == 14                  )
11097f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      {
1110aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE
1111aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( cur - first > FT_MAX_CHARMAP_CACHEABLE )
1112aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
1113aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_ERROR(( "find_unicode_charmap: UVS cmap is found "
1114aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                     "at too late position (%d)\n", cur - first ));
1115aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          continue;
1116aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        }
1117aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
1118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return cur[0];
11197f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      }
1120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return NULL;
1123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
1129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    open_face                                                          */
1130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
1132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    This function does some work for FT_Open_Face().                   */
1133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  open_face( FT_Driver      driver,
1136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Stream      stream,
1137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Long        face_index,
1138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Int         num_params,
1139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Parameter*  params,
1140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Face       *aface )
1141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory         memory;
1143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class   clazz;
1144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face           face = 0;
1145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error          error, error2;
1146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face_Internal  internal = NULL;
1147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clazz  = driver->clazz;
1150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = driver->root.memory;
1151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* allocate the face object and perform basic initialization */
1153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( face, clazz->face_object_size ) )
1154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
1155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( internal ) )
1157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
1158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->internal = internal;
1160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->driver   = driver;
1162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->memory   = memory;
1163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->stream   = stream;
1164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_CONFIG_OPTION_INCREMENTAL
1166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      int  i;
1168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->internal->incremental_interface = 0;
1171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( i = 0; i < num_params && !face->internal->incremental_interface;
1172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            i++ )
1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( params[i].tag == FT_PARAM_TAG_INCREMENTAL )
1174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          face->internal->incremental_interface =
1175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            (FT_Incremental_Interface)params[i].data;
1176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
1178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->init_face )
1180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = clazz->init_face( stream,
1181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                face,
1182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                (FT_Int)face_index,
1183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                num_params,
1184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                params );
1185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
1187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* select Unicode charmap by default */
1189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error2 = find_unicode_charmap( face );
1190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if no Unicode charmap can be found, FT_Err_Invalid_CharMap_Handle */
1192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* is returned.                                                      */
1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* no error should happen, but we want to play safe */
1195727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( error2 && FT_ERR_NEQ( error2, Invalid_CharMap_Handle ) )
1196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = error2;
1198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
1199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *aface = face;
1202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
1204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      destroy_charmaps( face, memory );
1207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( clazz->done_face )
1208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        clazz->done_face( face );
1209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( internal );
1210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( face );
1211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *aface = 0;
1212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* there's a Mac-specific extended implementation of FT_New_Face() */
1219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* in src/base/ftmac.c                                             */
1220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
122141371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#ifndef FT_MACINTOSH
1222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
1224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
1226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_New_Face( FT_Library   library,
1227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               const char*  pathname,
1228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Long      face_index,
1229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Face     *aface )
1230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Open_Args  args;
1232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `library' and `aface' delayed to FT_Open_Face() */
1235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !pathname )
1236727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
1237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.flags    = FT_OPEN_PATHNAME;
1239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.pathname = (char*)pathname;
124077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    args.stream   = NULL;
1241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Open_Face( library, &args, face_index, aface );
1243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
124541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#endif
1246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
1249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
1251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_New_Memory_Face( FT_Library      library,
1252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      const FT_Byte*  file_base,
1253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Long         file_size,
1254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Long         face_index,
1255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Face        *aface )
1256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Open_Args  args;
1258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `library' and `face' delayed to FT_Open_Face() */
1261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !file_base )
1262727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
1263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.flags       = FT_OPEN_MEMORY;
1265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.memory_base = file_base;
1266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.memory_size = file_size;
126777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    args.stream      = NULL;
1268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Open_Face( library, &args, face_index, aface );
1270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
127377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#ifdef FT_CONFIG_OPTION_MAC_FONTS
1274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The behavior here is very similar to that in base/ftmac.c, but it     */
1276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* is designed to work on non-mac systems, so no mac specific calls.     */
1277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* We look at the file and determine if it is a mac dfont file or a mac  */
1279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* resource file, or a macbinary file containing a mac resource file.    */
1280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Unlike ftmac I'm not going to look at a `FOND'.  I don't really see   */
1282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* the point, especially since there may be multiple `FOND' resources.   */
1283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Instead I'll just look for `sfnt' and `POST' resources, ordered as    */
1284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* they occur in the file.                                               */
1285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Note that multiple `POST' resources do not mean multiple postscript   */
1287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* fonts; they all get jammed together to make what is essentially a     */
1288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* pfb file.                                                             */
1289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* We aren't interested in `NFNT' or `FONT' bitmap resources.            */
1291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* As soon as we get an `sfnt' load it into memory and pass it off to    */
1293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* FT_Open_Face.                                                         */
1294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* If we have a (set of) `POST' resources, massage them into a (memory)  */
1296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* pfb file and pass that to FT_Open_Face.  (As with ftmac.c I'm not     */
1297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* going to try to save the kerning info.  After all that lives in the   */
1298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* `FOND' which isn't in the file containing the `POST' resources so     */
1299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* we don't really have access to it.                                    */
1300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
130277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* Finalizer for a memory stream; gets called by FT_Done_Face(). */
130377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* It frees the memory it uses.                                  */
130477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* From ftmac.c.                                                 */
1305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  memory_stream_close( FT_Stream  stream )
1307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = stream->memory;
1309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( stream->base );
1312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->size  = 0;
1314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->base  = 0;
1315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->close = 0;
1316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Create a new memory stream from a buffer and a size. */
132077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* From ftmac.c.                                        */
1321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  new_memory_stream( FT_Library           library,
1323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Byte*             base,
1324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_ULong             size,
1325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream_CloseFunc  close,
1326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Stream           *astream )
1327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
1329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory;
1330aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_Stream  stream = NULL;
1331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
1334727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Library_Handle );
1335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !base )
1337727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
1338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *astream = 0;
1340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = library->memory;
1341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( stream ) )
1342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream_OpenMemory( stream, base, size );
1345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream->close = close;
1347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *astream = stream;
1349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Create a new FT_Face given a buffer and a driver name. */
1356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* from ftmac.c */
135777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  FT_LOCAL_DEF( FT_Error )
1358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  open_face_from_buffer( FT_Library   library,
1359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Byte*     base,
1360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_ULong     size,
1361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Long      face_index,
1362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         const char*  driver_name,
1363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Face     *aface )
1364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Open_Args  args;
1366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error      error;
1367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream     stream = NULL;
1368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory     memory = library->memory;
1369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = new_memory_stream( library,
1372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               base,
1373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               size,
1374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               memory_stream_close,
1375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               &stream );
1376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( base );
1379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
1380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.flags = FT_OPEN_STREAM;
1383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    args.stream = stream;
1384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( driver_name )
1385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      args.flags = args.flags | FT_OPEN_DRIVER;
1387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      args.driver = FT_Get_Module( library, driver_name );
1388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
139077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#ifdef FT_MACINTOSH
139177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* At this point, face_index has served its purpose;      */
139277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* whoever calls this function has already used it to     */
139377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* locate the correct font data.  We should not propagate */
139477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* this index to FT_Open_Face() (unless it is negative).  */
139577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
139677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( face_index > 0 )
139777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      face_index = 0;
139877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#endif
139977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
1400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Open_Face( library, &args, face_index, aface );
1401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error == FT_Err_Ok )
1403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
1404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
140577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#ifdef FT_MACINTOSH
140677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      FT_Stream_Free( stream, 0 );
140777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#else
1408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_Close( stream );
1410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( stream );
1411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
141277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#endif
1413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
141877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* Look up `TYP1' or `CID ' table from sfnt table directory.       */
141977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* `offset' and `length' must exclude the binary header in tables. */
142077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
142177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* Type 1 and CID-keyed font drivers should recognize sfnt-wrapped */
142277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* format too.  Here, since we can't expect that the TrueType font */
142377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* driver is loaded unconditially, we must parse the font by       */
142477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* ourselves.  We are only interested in the name of the table and */
142577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* the offset.                                                     */
142677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
142777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  static FT_Error
142877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  ft_lookup_PS_in_sfnt_stream( FT_Stream  stream,
142977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                               FT_Long    face_index,
143077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                               FT_ULong*  offset,
143177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                               FT_ULong*  length,
143277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                               FT_Bool*   is_sfnt_cid )
143377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  {
143477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Error   error;
143577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_UShort  numTables;
143677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Long    pstable_index;
143777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_ULong   tag;
143877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    int        i;
143977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
144077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
144177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    *offset = 0;
144277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    *length = 0;
144377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    *is_sfnt_cid = FALSE;
144477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
144577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* TODO: support for sfnt-wrapped PS/CID in TTC format */
144677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
144777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* version check for 'typ1' (should be ignored?) */
144877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( FT_READ_ULONG( tag ) )
144977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      return error;
145077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( tag != TTAG_typ1 )
1451727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unknown_File_Format );
145277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
145377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( FT_READ_USHORT( numTables ) )
145477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      return error;
145577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( FT_STREAM_SKIP( 2 * 3 ) ) /* skip binary search header */
145677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      return error;
145777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
145877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    pstable_index = -1;
145977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    *is_sfnt_cid  = FALSE;
146077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
146177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    for ( i = 0; i < numTables; i++ )
146277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    {
146377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      if ( FT_READ_ULONG( tag )     || FT_STREAM_SKIP( 4 )      ||
146477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner           FT_READ_ULONG( *offset ) || FT_READ_ULONG( *length ) )
146577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        return error;
146677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
146777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      if ( tag == TTAG_CID )
146877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      {
146977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        pstable_index++;
147077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        *offset += 22;
147177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        *length -= 22;
147277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        *is_sfnt_cid = TRUE;
147377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        if ( face_index < 0 )
147477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          return FT_Err_Ok;
147577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      }
147677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      else if ( tag == TTAG_TYP1 )
147777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      {
147877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        pstable_index++;
147977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        *offset += 24;
148077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        *length -= 24;
148177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        *is_sfnt_cid = FALSE;
148277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        if ( face_index < 0 )
148377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          return FT_Err_Ok;
148477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      }
148577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      if ( face_index >= 0 && pstable_index == face_index )
148677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        return FT_Err_Ok;
148777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    }
1488727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_THROW( Table_Missing );
148977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  }
149077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
149177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
149277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  FT_LOCAL_DEF( FT_Error )
149377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  open_face_PS_from_sfnt_stream( FT_Library     library,
149477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                 FT_Stream      stream,
149577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                 FT_Long        face_index,
149677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                 FT_Int         num_params,
149777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                 FT_Parameter  *params,
149877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                 FT_Face       *aface )
149977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  {
150077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Error   error;
150177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Memory  memory = library->memory;
150277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_ULong   offset, length;
150377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Long    pos;
150477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Bool    is_sfnt_cid;
1505aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_Byte*   sfnt_ps = NULL;
150677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
150777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_UNUSED( num_params );
150877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_UNUSED( params );
150977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
151077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
151177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    pos = FT_Stream_Pos( stream );
151277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
151377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    error = ft_lookup_PS_in_sfnt_stream( stream,
151477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                         face_index,
151577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                         &offset,
151677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                         &length,
151777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                         &is_sfnt_cid );
151877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( error )
151977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      goto Exit;
152077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
152177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( FT_Stream_Seek( stream, pos + offset ) )
152277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      goto Exit;
152377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
152477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( FT_ALLOC( sfnt_ps, (FT_Long)length ) )
152577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      goto Exit;
152677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
152777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    error = FT_Stream_Read( stream, (FT_Byte *)sfnt_ps, length );
152877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( error )
152977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      goto Exit;
153077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
153177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    error = open_face_from_buffer( library,
153277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                   sfnt_ps,
153377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                   length,
1534727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                   FT_MIN( face_index, 0 ),
153577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                   is_sfnt_cid ? "cid" : "type1",
153677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                   aface );
153777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  Exit:
153877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    {
153977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      FT_Error  error1;
154077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
154177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
1542727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( FT_ERR_EQ( error, Unknown_File_Format ) )
154377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      {
154477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        error1 = FT_Stream_Seek( stream, pos );
154577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        if ( error1 )
154677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          return error1;
154777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      }
154877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
154977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      return error;
155077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    }
155177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  }
155277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
155377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
155441371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#ifndef FT_MACINTOSH
155577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
1556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The resource header says we've got resource_cnt `POST' (type1) */
1557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* resources in this file.  They all need to be coalesced into    */
1558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* one lump which gets passed on to the type1 driver.             */
1559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Here can be only one PostScript font in a file so face_index   */
1560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* must be 0 (or -1).                                             */
1561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                */
1562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Mac_Read_POST_Resource( FT_Library  library,
1564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Stream   stream,
1565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Long    *offsets,
1566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Long     resource_cnt,
1567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Long     face_index,
1568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Face    *aface )
1569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1570727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error   error  = FT_ERR( Cannot_Open_Resource );
1571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = library->memory;
1572aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_Byte*   pfb_data = NULL;
1573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int        i, type, flags;
1574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    len;
1575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    pfb_len, pfb_pos, pfb_lenpos;
1576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    rlen, temp;
1577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face_index == -1 )
1580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face_index = 0;
1581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face_index != 0 )
1582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
1583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Find the length of all the POST resources, concatenated.  Assume */
1585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* worst case (each resource in its own section).                   */
1586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_len = 0;
1587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0; i < resource_cnt; ++i )
1588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Stream_Seek( stream, offsets[i] );
1590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_READ_LONG( temp ) )
1593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pfb_len += temp + 6;
1595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) )
1598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[0] = 0x80;
1601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[1] = 1;            /* Ascii section */
1602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[2] = 0;            /* 4-byte length, fill in later */
1603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[3] = 0;
1604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[4] = 0;
1605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[5] = 0;
1606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_pos     = 6;
1607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_lenpos  = 2;
1608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    len = 0;
1610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    type = 1;
1611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0; i < resource_cnt; ++i )
1612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Stream_Seek( stream, offsets[i] );
1614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit2;
1616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_READ_LONG( rlen ) )
1617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_READ_USHORT( flags ) )
1619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1620aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_TRACE3(( "POST fragment[%d]: offsets=0x%08x, rlen=0x%08x, flags=0x%04x\n",
1621aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                   i, offsets[i], rlen, flags ));
1622aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1623aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* postpone the check of rlen longer than buffer until FT_Stream_Read() */
1624aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( ( flags >> 8 ) == 0 )        /* Comment, should not be loaded */
1625aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        continue;
1626aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1627aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* the flags are part of the resource, so rlen >= 2.  */
1628aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* but some fonts declare rlen = 0 for empty fragment */
1629aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( rlen > 2 )
1630aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        rlen -= 2;
1631aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      else
1632aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        rlen = 0;
1633aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ( flags >> 8 ) == type )
1635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        len += rlen;
1636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
1637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1638aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( pfb_lenpos + 3 > pfb_len + 2 )
1639aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          goto Exit2;
1640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_lenpos    ] = (FT_Byte)( len );
1641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
1642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
1643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 );
1644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ( flags >> 8 ) == 5 )      /* End of font mark */
1646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
1647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1648aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( pfb_pos + 6 > pfb_len + 2 )
1649aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          goto Exit2;
1650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_pos++] = 0x80;
1651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        type = flags >> 8;
1653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        len = rlen;
1654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_pos++] = (FT_Byte)type;
1656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_lenpos          = pfb_pos;
1657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_pos++] = 0;        /* 4-byte length, fill in later */
1658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_pos++] = 0;
1659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_pos++] = 0;
1660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        pfb_data[pfb_pos++] = 0;
1661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1663727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_ERR( Cannot_Open_Resource );
1664aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( pfb_pos > pfb_len || pfb_pos + rlen > pfb_len )
1665aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        goto Exit2;
1666aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Stream_Read( stream, (FT_Byte *)pfb_data + pfb_pos, rlen );
1668aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( error )
1669aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        goto Exit2;
1670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pfb_pos += rlen;
1671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1673aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( pfb_pos + 2 > pfb_len + 2 )
1674aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      goto Exit2;
1675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[pfb_pos++] = 0x80;
1676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[pfb_pos++] = 3;
1677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1678aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( pfb_lenpos + 3 > pfb_len + 2 )
1679aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      goto Exit2;
1680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[pfb_lenpos    ] = (FT_Byte)( len );
1681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
1682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
1683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 );
1684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return open_face_from_buffer( library,
1686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  pfb_data,
1687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  pfb_pos,
1688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  face_index,
1689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  "type1",
1690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  aface );
1691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit2:
1693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( pfb_data );
1694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The resource header says we've got resource_cnt `sfnt'      */
1701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* (TrueType/OpenType) resources in this file.  Look through   */
1702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* them for the one indicated by face_index, load it into mem, */
1703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* pass it on the the truetype driver and return it.           */
1704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                             */
1705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Mac_Read_sfnt_Resource( FT_Library  library,
1707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Stream   stream,
1708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Long    *offsets,
1709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Long     resource_cnt,
1710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Long     face_index,
1711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          FT_Face    *aface )
1712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = library->memory;
1714aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_Byte*   sfnt_data = NULL;
1715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
1716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    flag_offset;
1717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    rlen;
1718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int        is_cff;
1719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    face_index_in_resource = 0;
1720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face_index == -1 )
1723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face_index = 0;
1724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face_index >= resource_cnt )
1725727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Cannot_Open_Resource );
1726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    flag_offset = offsets[face_index];
1728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_Seek( stream, flag_offset );
1729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_READ_LONG( rlen ) )
1733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( rlen == -1 )
1735727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Cannot_Open_Resource );
1736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
173777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    error = open_face_PS_from_sfnt_stream( library,
173877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                           stream,
173977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                           face_index,
174077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                           0, NULL,
174177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                           aface );
174277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( !error )
174377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      goto Exit;
174477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
174577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    /* rewind sfnt stream before open_face_PS_from_sfnt_stream() */
174677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    if ( FT_Stream_Seek( stream, flag_offset + 4 ) )
174777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      goto Exit;
174877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
1749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( sfnt_data, (FT_Long)rlen ) )
1750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
1751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_Read( stream, (FT_Byte *)sfnt_data, rlen );
1752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
175577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    is_cff = rlen > 4 && !ft_memcmp( sfnt_data, "OTTO", 4 );
1756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = open_face_from_buffer( library,
1757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   sfnt_data,
1758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   rlen,
1759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   face_index_in_resource,
1760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   is_cff ? "cff" : "truetype",
1761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   aface );
1762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Check for a valid resource fork header, or a valid dfont    */
1769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* header.  In a resource fork the first 16 bytes are repeated */
1770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* at the location specified by bytes 4-7.  In a dfont bytes   */
1771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* 4-7 point to 16 bytes of zeroes instead.                    */
1772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                             */
1773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  IsMacResource( FT_Library  library,
1775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Stream   stream,
1776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Long     resource_offset,
1777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Long     face_index,
1778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Face    *aface )
1779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = library->memory;
1781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
1782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    map_offset, rdara_pos;
1783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    *data_offsets;
1784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    count;
1785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Raccess_Get_HeaderInfo( library, stream, resource_offset,
1788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       &map_offset, &rdara_pos );
1789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
1791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Raccess_Get_DataOffsets( library, stream,
1793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                        map_offset, rdara_pos,
179477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                        TTAG_POST,
1795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                        &data_offsets, &count );
1796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
1797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = Mac_Read_POST_Resource( library, stream, data_offsets, count,
1799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      face_index, aface );
1800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( data_offsets );
1801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* POST exists in an LWFN providing a single face */
1802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !error )
1803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        (*aface)->num_faces = 1;
1804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
1805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Raccess_Get_DataOffsets( library, stream,
1808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                        map_offset, rdara_pos,
180977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                        TTAG_sfnt,
1810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                        &data_offsets, &count );
1811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
1812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Long  face_index_internal = face_index % count;
1814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = Mac_Read_sfnt_Resource( library, stream, data_offsets, count,
1817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      face_index_internal, aface );
1818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( data_offsets );
1819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !error )
1820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        (*aface)->num_faces = count;
1821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Check for a valid macbinary header, and if we find one   */
1828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* check that the (flattened) resource fork in it is valid. */
1829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                          */
1830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  IsMacBinary( FT_Library  library,
1832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Stream   stream,
1833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Long     face_index,
1834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Face    *aface )
1835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned char  header[128];
1837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error       error;
1838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long        dlen, offset;
1839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( NULL == stream )
1842727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Stream_Operation );
1843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_Seek( stream, 0 );
1845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_Read( stream, (FT_Byte*)header, 128 );
1849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if (            header[ 0] !=  0 ||
1853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    header[74] !=  0 ||
1854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    header[82] !=  0 ||
1855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    header[ 1] ==  0 ||
1856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    header[ 1] >  33 ||
1857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    header[63] !=  0 ||
1858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         header[2 + header[1]] !=  0 )
1859727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unknown_File_Format );
1860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    dlen = ( header[0x53] << 24 ) |
1862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           ( header[0x54] << 16 ) |
1863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           ( header[0x55] <<  8 ) |
1864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             header[0x56];
1865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 0
1866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    rlen = ( header[0x57] << 24 ) |
1867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           ( header[0x58] << 16 ) |
1868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           ( header[0x59] <<  8 ) |
1869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             header[0x5a];
1870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* 0 */
1871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    offset = 128 + ( ( dlen + 127 ) & ~127 );
1872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return IsMacResource( library, stream, offset, face_index, aface );
1874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  load_face_in_embedded_rfork( FT_Library           library,
1882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_Stream            stream,
1883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_Long              face_index,
1884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_Face             *aface,
1885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               const FT_Open_Args  *args )
1886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
1889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_raccess
1890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = library->memory;
1892727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error   error  = FT_ERR( Unknown_File_Format );
1893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int        i;
1894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    char *     file_names[FT_RACCESS_N_RULES];
1896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long    offsets[FT_RACCESS_N_RULES];
1897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   errors[FT_RACCESS_N_RULES];
18987f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    FT_Bool    is_darwin_vfs, vfs_rfork_has_no_font = FALSE; /* not tested */
1899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Open_Args  args2;
190177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner    FT_Stream     stream2 = 0;
1902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Raccess_Guess( library, stream,
1905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      args->pathname, file_names, offsets, errors );
1906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
1908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
190941371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      is_darwin_vfs = ft_raccess_rule_by_darwin_vfs( library, i );
19107f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      if ( is_darwin_vfs && vfs_rfork_has_no_font )
19117f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      {
19127f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        FT_TRACE3(( "Skip rule %d: darwin vfs resource fork"
19137f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner                    " is already checked and"
19147f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner                    " no font is found\n", i ));
19157f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        continue;
1916aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      }
19177f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
1918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( errors[i] )
1919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_TRACE3(( "Error[%d] has occurred in rule %d\n", errors[i], i ));
1921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        continue;
1922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      args2.flags    = FT_OPEN_PATHNAME;
1925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      args2.pathname = file_names[i] ? file_names[i] : args->pathname;
1926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_TRACE3(( "Try rule %d: %s (offset=%d) ...",
1928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  i, args2.pathname, offsets[i] ));
1929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Stream_New( library, &args2, &stream2 );
1931727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( is_darwin_vfs && FT_ERR_EQ( error, Cannot_Open_Stream ) )
19327f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        vfs_rfork_has_no_font = TRUE;
19337f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
1934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_TRACE3(( "failed\n" ));
1937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        continue;
1938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = IsMacResource( library, stream2, offsets[i],
1941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             face_index, aface );
1942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_Free( stream2, 0 );
1943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_TRACE3(( "%s\n", error ? "failed": "successful" ));
1945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !error )
1947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
19487f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      else if ( is_darwin_vfs )
19497f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner          vfs_rfork_has_no_font = TRUE;
1950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for (i = 0; i < FT_RACCESS_N_RULES; i++)
1953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( file_names[i] )
1955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_FREE( file_names[i] );
1956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Caller (load_mac_face) requires FT_Err_Unknown_File_Format. */
1959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1960727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_ERR( Unknown_File_Format );
1961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
1965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_objs
1966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
197077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner  /* Check for some macintosh formats without Carbon framework.    */
1971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Is this a macbinary file?  If so look at the resource fork.   */
1972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Is this a mac dfont file?                                     */
1973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Is this an old style resource fork? (in data)                 */
1974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Else call load_face_in_embedded_rfork to try extra rules      */
1975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* (defined in `ftrfork.c').                                     */
1976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                               */
1977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  load_mac_face( FT_Library           library,
1979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Stream            stream,
1980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Long              face_index,
1981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Face             *aface,
1982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const FT_Open_Args  *args )
1983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error error;
1985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( args );
1986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = IsMacBinary( library, stream, face_index, aface );
1989727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( FT_ERR_EQ( error, Unknown_File_Format ) )
1990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
1993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_raccess
1994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_TRACE3(( "Try as dfont: %s ...", args->pathname ));
1996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = IsMacResource( library, stream, 0, face_index, aface );
1998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_TRACE3(( "%s\n", error ? "failed" : "successful" ));
2000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
2002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_objs
2003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2006727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( ( FT_ERR_EQ( error, Unknown_File_Format )      ||
2007727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           FT_ERR_EQ( error, Invalid_Stream_Operation ) ) &&
2008727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease         ( args->flags & FT_OPEN_PATHNAME )               )
2009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = load_face_in_embedded_rfork( library, stream,
2010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           face_index, aface, args );
2011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
201377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#endif
2014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif  /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */
2016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Open_Face( FT_Library           library,
2022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                const FT_Open_Args*  args,
2023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Long              face_index,
2024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Face             *aface )
2025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error;
2027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver    driver;
2028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory    memory;
2029aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Stream    stream = NULL;
2030aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Face      face   = NULL;
2031aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_ListNode  node   = NULL;
2032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bool      external_stream;
2033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module*   cur;
2034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module*   limit;
2035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `library' delayed to */
2038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* FT_Stream_New()                     */
2039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ( !aface && face_index >= 0 ) || !args )
2041727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
2042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    external_stream = FT_BOOL( ( args->flags & FT_OPEN_STREAM ) &&
2044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               args->stream                     );
2045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* create input stream */
2047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_New( library, args, &stream );
2048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
2049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail3;
2050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = library->memory;
2052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* If the font driver is specified in the `args' structure, use */
2054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* it.  Otherwise, we scan the list of registered drivers.      */
2055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ( args->flags & FT_OPEN_DRIVER ) && args->driver )
2056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      driver = FT_DRIVER( args->driver );
2058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* not all modules are drivers, so check... */
2060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_MODULE_IS_DRIVER( driver ) )
2061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Int         num_params = 0;
2063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Parameter*  params     = 0;
2064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( args->flags & FT_OPEN_PARAMS )
2067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
2068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          num_params = args->num_params;
2069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          params     = args->params;
2070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
2071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = open_face( driver, stream, face_index,
2073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           num_params, params, &face );
2074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !error )
2075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Success;
2076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
2078727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_THROW( Invalid_Handle );
2079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_Free( stream, external_stream );
2081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
2082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
2084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2085727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_ERR( Missing_Module );
2086727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* check each font driver for an appropriate format */
2088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur   = library->modules;
2089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      limit = cur + library->num_modules;
2090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; cur < limit; cur++ )
2092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* not all modules are font drivers, so check... */
2094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_MODULE_IS_DRIVER( cur[0] ) )
2095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
2096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Int         num_params = 0;
2097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Parameter*  params     = 0;
2098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          driver = FT_DRIVER( cur[0] );
2101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( args->flags & FT_OPEN_PARAMS )
2103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
2104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            num_params = args->num_params;
2105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            params     = args->params;
2106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
2107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          error = open_face( driver, stream, face_index,
2109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             num_params, params, &face );
2110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( !error )
2111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Success;
2112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
211377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#ifdef FT_CONFIG_OPTION_MAC_FONTS
211477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          if ( ft_strcmp( cur[0]->clazz->module_name, "truetype" ) == 0 &&
2115727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease               FT_ERR_EQ( error, Table_Missing )                        )
211677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          {
211777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            /* TrueType but essential tables are missing */
211877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            if ( FT_Stream_Seek( stream, 0 ) )
211977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner              break;
212077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
212177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            error = open_face_PS_from_sfnt_stream( library,
212277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                                   stream,
212377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                                   face_index,
212477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                                   num_params,
212577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                                   params,
212677f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner                                                   aface );
212777f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            if ( !error )
212877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            {
212977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner              FT_Stream_Free( stream, external_stream );
213077f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner              return error;
213177f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner            }
213277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner          }
213377f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner#endif
213477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner
2135727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          if ( FT_ERR_NEQ( error, Unknown_File_Format ) )
2136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Fail3;
2137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
2138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2140727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    Fail3:
2141727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      /* If we are on the mac, and we get an                          */
2142727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      /* FT_Err_Invalid_Stream_Operation it may be because we have an */
2143727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      /* empty data fork, so we need to check the resource fork.      */
2144727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( FT_ERR_NEQ( error, Cannot_Open_Stream )       &&
2145727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           FT_ERR_NEQ( error, Unknown_File_Format )      &&
2146727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           FT_ERR_NEQ( error, Invalid_Stream_Operation ) )
2147727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        goto Fail2;
2148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if !defined( FT_MACINTOSH ) && defined( FT_CONFIG_OPTION_MAC_FONTS )
2150727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = load_mac_face( library, stream, face_index, aface, args );
2151727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( !error )
2152727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
2153727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* We don't want to go to Success here.  We've already done that. */
2154727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* On the other hand, if we succeeded we still need to close this */
2155727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* stream (we opened a different stream which extracted the       */
2156727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* interesting information out of this stream here.  That stream  */
2157727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* will still be open and the face will point to it).             */
2158727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_Stream_Free( stream, external_stream );
2159727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        return error;
2160727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
2161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2162727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( FT_ERR_NEQ( error, Unknown_File_Format ) )
2163727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        goto Fail2;
2164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif  /* !FT_MACINTOSH && FT_CONFIG_OPTION_MAC_FONTS */
2165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* no driver is able to handle this format */
2167727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Unknown_File_Format );
2168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail2:
2170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_Free( stream, external_stream );
2171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
2172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Success:
2175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE4(( "FT_Open_Face: New face object, adding to list\n" ));
2176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* set the FT_FACE_FLAG_EXTERNAL_STREAM bit for FT_Done_Face */
2178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( external_stream )
2179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;
2180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* add the face object to its driver's list */
2182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( node ) )
2183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
2184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node->data = face;
2186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* don't assume driver is the same as face->driver, so use */
2187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* face->driver instead.                                   */
2188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_List_Add( &face->driver->faces_list, node );
2189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* now allocate a glyph slot object for the face */
2191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE4(( "FT_Open_Face: Creating glyph slot\n" ));
2192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face_index >= 0 )
2194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_New_GlyphSlot( face, NULL );
2196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
2197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
2198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* finally, allocate a size object for the face */
2200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Size  size;
2202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_TRACE4(( "FT_Open_Face: Creating size object\n" ));
2205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = FT_New_Size( face, &size );
2207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
2208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
2209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->size = size;
2211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* some checks */
2215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_IS_SCALABLE( face ) )
2217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( face->height < 0 )
2219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->height = (FT_Short)-face->height;
2220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !FT_HAS_VERTICAL( face ) )
2222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->max_advance_height = (FT_Short)face->height;
2223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_HAS_FIXED_SIZES( face ) )
2226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int  i;
2228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( i = 0; i < face->num_fixed_sizes; i++ )
2231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Bitmap_Size*  bsize = face->available_sizes + i;
2233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( bsize->height < 0 )
2236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          bsize->height = (FT_Short)-bsize->height;
2237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( bsize->x_ppem < 0 )
2238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          bsize->x_ppem = (FT_Short)-bsize->x_ppem;
2239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( bsize->y_ppem < 0 )
2240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          bsize->y_ppem = -bsize->y_ppem;
2241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* initialize internal face data */
2245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Face_Internal  internal = face->internal;
2247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.xx = 0x10000L;
2250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.xy = 0;
2251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.yx = 0;
2252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_matrix.yy = 0x10000L;
2253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_delta.x = 0;
2255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      internal->transform_delta.y = 0;
2256aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2257aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      internal->refcount = 1;
2258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( aface )
2261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *aface = face;
2262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
2263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Done_Face( face );
2264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
2266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
2268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Done_Face( face );
2269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
2271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE4(( "FT_Open_Face: Return %d\n", error ));
2272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Attach_File( FT_Face      face,
2281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  const char*  filepathname )
2282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Open_Args  open;
2284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `face' delayed to FT_Attach_Stream() */
2287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !filepathname )
2289727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
2290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    open.stream   = NULL;
2292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    open.flags    = FT_OPEN_PATHNAME;
2293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    open.pathname = (char*)filepathname;
2294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Attach_Stream( face, &open );
2296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Attach_Stream( FT_Face        face,
2303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Open_Args*  parameters )
2304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream  stream;
2306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
2307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver  driver;
2308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz;
2310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `parameters' delayed to FT_Stream_New() */
2313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
2315727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
2316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    driver = face->driver;
2318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !driver )
2319727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Driver_Handle );
2320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Stream_New( driver->root.library, parameters, &stream );
2322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
2323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
2324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* we implement FT_Attach_Stream in each driver through the */
2326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* `attach_file' interface                                  */
2327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2328727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    error = FT_ERR( Unimplemented_Feature );
2329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clazz = driver->clazz;
2330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->attach_file )
2331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = clazz->attach_file( face, stream );
2332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* close the attached stream */
2334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream_Free( stream,
2335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    (FT_Bool)( parameters->stream &&
2336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               ( parameters->flags & FT_OPEN_STREAM ) ) );
2337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
2339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2346aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  FT_Reference_Face( FT_Face  face )
2347aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  {
2348aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    face->internal->refcount++;
2349aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2350aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    return FT_Err_Ok;
2351aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  }
2352aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2353aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2354aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  /* documentation is in freetype.h */
2355aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2356aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  FT_EXPORT_DEF( FT_Error )
2357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Done_Face( FT_Face  face )
2358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error;
2360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver    driver;
2361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory    memory;
2362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ListNode  node;
2363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2365727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    error = FT_ERR( Invalid_Face_Handle );
2366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face && face->driver )
2367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2368aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      face->internal->refcount--;
2369aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( face->internal->refcount > 0 )
2370aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        error = FT_Err_Ok;
2371aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      else
2372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2373aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        driver = face->driver;
2374aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        memory = driver->root.memory;
2375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2376aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        /* find face in driver's list */
2377aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        node = FT_List_Find( &driver->faces_list, face );
2378aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( node )
2379aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
2380aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          /* remove face object from the driver's list */
2381aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_List_Remove( &driver->faces_list, node );
2382aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_FREE( node );
2383aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2384aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          /* now destroy the object proper */
2385aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          destroy_face( memory, face, driver );
2386aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          error = FT_Err_Ok;
2387aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        }
2388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2390aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
2391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
2396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_New_Size( FT_Face   face,
2399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Size  *asize )
2400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error         error;
2402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory        memory;
2403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver        driver;
2404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz;
2405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Size          size = 0;
2407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ListNode      node = 0;
2408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
2411727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
2412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !asize )
2414727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Size_Handle );
2415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face->driver )
2417727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Driver_Handle );
2418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *asize = 0;
2420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    driver = face->driver;
2422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clazz  = driver->clazz;
2423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = face->memory;
2424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Allocate new size object and perform basic initialisation */
2426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( size, clazz->size_object_size ) || FT_NEW( node ) )
2427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
2428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    size->face = face;
2430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* for now, do not use any internal fields in size objects */
2432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    size->internal = 0;
2433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->init_size )
2435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = clazz->init_size( size );
2436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* in case of success, add to the face's list */
2438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
2439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *asize     = size;
2441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      node->data = size;
2442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_List_Add( &face->sizes_list, node );
2443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
2446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
2447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( node );
2449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( size );
2450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
2457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Done_Size( FT_Size  size )
2460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error;
2462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver    driver;
2463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory    memory;
2464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face      face;
2465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ListNode  node;
2466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !size )
2469727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Size_Handle );
2470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face = size->face;
2472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
2473727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
2474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    driver = face->driver;
2476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !driver )
2477727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Driver_Handle );
2478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = driver->root.memory;
2480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_Err_Ok;
2482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node  = FT_List_Find( &face->sizes_list, size );
2483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( node )
2484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_List_Remove( &face->sizes_list, node );
2486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( node );
2487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( face->size == size )
2489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->size = 0;
2491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( face->sizes_list.head )
2492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          face->size = (FT_Size)(face->sizes_list.head->data);
2493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      destroy_size( memory, size, driver );
2496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
2498727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Invalid_Size_Handle );
2499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
2505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
2507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Match_Size( FT_Face          face,
2508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Size_Request  req,
2509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Bool          ignore_width,
2510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_ULong*        size_index )
2511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int   i;
2513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long  w, h;
2514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_HAS_FIXED_SIZES( face ) )
2517727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
2518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* FT_Bitmap_Size doesn't provide enough info... */
2520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )
2521727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unimplemented_Feature );
2522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    w = FT_REQUEST_WIDTH ( req );
2524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    h = FT_REQUEST_HEIGHT( req );
2525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( req->width && !req->height )
2527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      h = w;
2528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( !req->width && req->height )
2529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      w = h;
2530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    w = FT_PIX_ROUND( w );
2532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    h = FT_PIX_ROUND( h );
2533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0; i < face->num_fixed_sizes; i++ )
2535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Bitmap_Size*  bsize = face->available_sizes + i;
2537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( h != FT_PIX_ROUND( bsize->y_ppem ) )
2540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        continue;
2541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( w == FT_PIX_ROUND( bsize->x_ppem ) || ignore_width )
2543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2544727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_TRACE3(( "FT_Match_Size: bitmap strike %d matches\n", i ));
2545727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( size_index )
2547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *size_index = (FT_ULong)i;
2548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return FT_Err_Ok;
2550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2553727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_THROW( Invalid_Pixel_Size );
2554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
2558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
2560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_synthesize_vertical_metrics( FT_Glyph_Metrics*  metrics,
2561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  FT_Pos             advance )
2562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2563295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_Pos  height = metrics->height;
2564295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
2565295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
2566295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* compensate for glyph with bbox above/below the baseline */
2567295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( metrics->horiBearingY < 0 )
2568295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    {
2569295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      if ( height < metrics->horiBearingY )
2570295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        height = metrics->horiBearingY;
2571295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    }
2572295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    else if ( metrics->horiBearingY > 0 )
2573295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      height -= metrics->horiBearingY;
2574295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
2575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the factor 1.2 is a heuristical value */
2576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !advance )
2577295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      advance = height * 12 / 10;
2578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2579295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    metrics->vertBearingX = metrics->horiBearingX - metrics->horiAdvance / 2;
2580295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    metrics->vertBearingY = ( advance - height ) / 2;
2581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->vertAdvance  = advance;
2582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
2586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_recompute_scaled_metrics( FT_Face           face,
2587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_Size_Metrics*  metrics )
2588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Compute root ascender, descender, test height, and max_advance */
2590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef GRID_FIT_METRICS
2592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->ascender    = FT_PIX_CEIL( FT_MulFix( face->ascender,
2593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                   metrics->y_scale ) );
2594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->descender   = FT_PIX_FLOOR( FT_MulFix( face->descender,
2596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                    metrics->y_scale ) );
2597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->height      = FT_PIX_ROUND( FT_MulFix( face->height,
2599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                    metrics->y_scale ) );
2600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->max_advance = FT_PIX_ROUND( FT_MulFix( face->max_advance_width,
2602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                    metrics->x_scale ) );
2603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !GRID_FIT_METRICS */
2604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->ascender    = FT_MulFix( face->ascender,
2605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      metrics->y_scale );
2606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->descender   = FT_MulFix( face->descender,
2608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      metrics->y_scale );
2609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->height      = FT_MulFix( face->height,
2611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      metrics->y_scale );
2612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->max_advance = FT_MulFix( face->max_advance_width,
2614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      metrics->x_scale );
2615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* !GRID_FIT_METRICS */
2616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
2620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Select_Metrics( FT_Face   face,
2621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_ULong  strike_index )
2622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Size_Metrics*  metrics;
2624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bitmap_Size*   bsize;
2625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics = &face->size->metrics;
2628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    bsize   = face->available_sizes + strike_index;
2629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->x_ppem = (FT_UShort)( ( bsize->x_ppem + 32 ) >> 6 );
2631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics->y_ppem = (FT_UShort)( ( bsize->y_ppem + 32 ) >> 6 );
2632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_IS_SCALABLE( face ) )
2634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->x_scale = FT_DivFix( bsize->x_ppem,
2636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                    face->units_per_EM );
2637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->y_scale = FT_DivFix( bsize->y_ppem,
2638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                    face->units_per_EM );
2639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_recompute_scaled_metrics( face, metrics );
2641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
2643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
264477f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      metrics->x_scale     = 1L << 16;
264577f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      metrics->y_scale     = 1L << 16;
2646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->ascender    = bsize->y_ppem;
2647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->descender   = 0;
2648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->height      = bsize->height << 6;
2649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->max_advance = bsize->x_ppem;
2650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2651bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2652bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "FT_Select_Metrics:\n" ));
2653bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  x scale: %d (%f)\n",
2654bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                metrics->x_scale, metrics->x_scale / 65536.0 ));
2655bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  y scale: %d (%f)\n",
2656bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                metrics->y_scale, metrics->y_scale / 65536.0 ));
2657bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  ascender: %f\n",    metrics->ascender / 64.0 ));
2658bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  descender: %f\n",   metrics->descender / 64.0 ));
2659bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  height: %f\n",      metrics->height / 64.0 ));
2660bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  max advance: %f\n", metrics->max_advance / 64.0 ));
2661bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  x ppem: %d\n",      metrics->x_ppem ));
2662bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  y ppem: %d\n",      metrics->y_ppem ));
2663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
2667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Request_Metrics( FT_Face          face,
2668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Size_Request  req )
2669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Size_Metrics*  metrics;
2671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    metrics = &face->size->metrics;
2674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_IS_SCALABLE( face ) )
2676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Long  w = 0, h = 0, scaled_w = 0, scaled_h = 0;
2678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      switch ( req->type )
2681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case FT_SIZE_REQUEST_TYPE_NOMINAL:
2683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        w = h = face->units_per_EM;
2684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
2685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case FT_SIZE_REQUEST_TYPE_REAL_DIM:
2687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        w = h = face->ascender - face->descender;
2688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
2689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case FT_SIZE_REQUEST_TYPE_BBOX:
2691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        w = face->bbox.xMax - face->bbox.xMin;
2692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        h = face->bbox.yMax - face->bbox.yMin;
2693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
2694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case FT_SIZE_REQUEST_TYPE_CELL:
2696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        w = face->max_advance_width;
2697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        h = face->ascender - face->descender;
2698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
2699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case FT_SIZE_REQUEST_TYPE_SCALES:
2701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->x_scale = (FT_Fixed)req->width;
2702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->y_scale = (FT_Fixed)req->height;
2703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !metrics->x_scale )
2704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          metrics->x_scale = metrics->y_scale;
2705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else if ( !metrics->y_scale )
2706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          metrics->y_scale = metrics->x_scale;
2707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Calculate_Ppem;
2708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      case FT_SIZE_REQUEST_TYPE_MAX:
2710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
2711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* to be on the safe side */
2714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( w < 0 )
2715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        w = -w;
2716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( h < 0 )
2718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        h = -h;
2719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      scaled_w = FT_REQUEST_WIDTH ( req );
2721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      scaled_h = FT_REQUEST_HEIGHT( req );
2722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* determine scales */
2724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( req->width )
2725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->x_scale = FT_DivFix( scaled_w, w );
2727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( req->height )
2729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
2730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          metrics->y_scale = FT_DivFix( scaled_h, h );
2731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( req->type == FT_SIZE_REQUEST_TYPE_CELL )
2733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
2734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( metrics->y_scale > metrics->x_scale )
2735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              metrics->y_scale = metrics->x_scale;
2736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            else
2737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              metrics->x_scale = metrics->y_scale;
2738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
2739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
2740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
2741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
2742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          metrics->y_scale = metrics->x_scale;
2743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          scaled_h = FT_MulDiv( scaled_w, h, w );
2744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
2745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
2747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        metrics->x_scale = metrics->y_scale = FT_DivFix( scaled_h, h );
2749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        scaled_w = FT_MulDiv( scaled_h, w, h );
2750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Calculate_Ppem:
2753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* calculate the ppems */
2754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )
2755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        scaled_w = FT_MulFix( face->units_per_EM, metrics->x_scale );
2757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        scaled_h = FT_MulFix( face->units_per_EM, metrics->y_scale );
2758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->x_ppem = (FT_UShort)( ( scaled_w + 32 ) >> 6 );
2761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      metrics->y_ppem = (FT_UShort)( ( scaled_h + 32 ) >> 6 );
2762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_recompute_scaled_metrics( face, metrics );
2764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
2766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ZERO( metrics );
276877f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      metrics->x_scale = 1L << 16;
276977f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner      metrics->y_scale = 1L << 16;
2770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2771bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2772bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "FT_Request_Metrics:\n" ));
2773bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  x scale: %d (%f)\n",
2774bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                metrics->x_scale, metrics->x_scale / 65536.0 ));
2775bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  y scale: %d (%f)\n",
2776bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                metrics->y_scale, metrics->y_scale / 65536.0 ));
2777bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  ascender: %f\n",    metrics->ascender / 64.0 ));
2778bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  descender: %f\n",   metrics->descender / 64.0 ));
2779bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  height: %f\n",      metrics->height / 64.0 ));
2780bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  max advance: %f\n", metrics->max_advance / 64.0 ));
2781bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  x ppem: %d\n",      metrics->x_ppem ));
2782bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    FT_TRACE5(( "  y ppem: %d\n",      metrics->y_ppem ));
2783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Select_Size( FT_Face  face,
2790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Int   strike_index )
2791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz;
2793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face || !FT_HAS_FIXED_SIZES( face ) )
2796727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
2797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( strike_index < 0 || strike_index >= face->num_fixed_sizes )
2799727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
2800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clazz = face->driver->clazz;
2802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->select_size )
2804bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
2805bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_Error  error;
2806bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2807bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2808bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      error = clazz->select_size( face->size, (FT_ULong)strike_index );
2809bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2810bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#ifdef FT_DEBUG_LEVEL_TRACE
2811bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      {
2812bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_Size_Metrics*  metrics = &face->size->metrics;
2813bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2814bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2815bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "FT_Select_Size (font driver's `select_size'):\n" ));
2816bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  x scale: %d (%f)\n",
2817bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                    metrics->x_scale, metrics->x_scale / 65536.0 ));
2818bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  y scale: %d (%f)\n",
2819bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                    metrics->y_scale, metrics->y_scale / 65536.0 ));
2820bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  ascender: %f\n",    metrics->ascender / 64.0 ));
2821bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  descender: %f\n",   metrics->descender / 64.0 ));
2822bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  height: %f\n",      metrics->height / 64.0 ));
2823bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  max advance: %f\n", metrics->max_advance / 64.0 ));
2824bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  x ppem: %d\n",      metrics->x_ppem ));
2825bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  y ppem: %d\n",      metrics->y_ppem ));
2826bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      }
2827bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#endif
2828bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2829bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      return error;
2830bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
2831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Select_Metrics( face, (FT_ULong)strike_index );
2833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Ok;
2835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Request_Size( FT_Face          face,
2842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Size_Request  req )
2843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver_Class  clazz;
2845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong         strike_index;
2846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
2849727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
2850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !req || req->width < 0 || req->height < 0 ||
2852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         req->type >= FT_SIZE_REQUEST_TYPE_MAX )
2853727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
2854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clazz = face->driver->clazz;
2856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->request_size )
2858bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
2859bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      FT_Error  error;
2860bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2861bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2862bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      error = clazz->request_size( face->size, req );
2863bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2864bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#ifdef FT_DEBUG_LEVEL_TRACE
2865bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      {
2866bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_Size_Metrics*  metrics = &face->size->metrics;
2867bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2868bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2869bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "FT_Request_Size (font driver's `request_size'):\n" ));
2870bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  x scale: %d (%f)\n",
2871bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                    metrics->x_scale, metrics->x_scale / 65536.0 ));
2872bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  y scale: %d (%f)\n",
2873bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly                    metrics->y_scale, metrics->y_scale / 65536.0 ));
2874bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  ascender: %f\n",    metrics->ascender / 64.0 ));
2875bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  descender: %f\n",   metrics->descender / 64.0 ));
2876bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  height: %f\n",      metrics->height / 64.0 ));
2877bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  max advance: %f\n", metrics->max_advance / 64.0 ));
2878bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  x ppem: %d\n",      metrics->x_ppem ));
2879bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly        FT_TRACE5(( "  y ppem: %d\n",      metrics->y_ppem ));
2880bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      }
2881bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly#endif
2882bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly
2883bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly      return error;
2884bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    }
2885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*
2887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * The reason that a driver doesn't have `request_size' defined is
2888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * either that the scaling here suffices or that the supported formats
2889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * are bitmap-only and size matching is not implemented.
2890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
2891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * In the latter case, a simple size matching is done.
2892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     */
2893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_IS_SCALABLE( face ) && FT_HAS_FIXED_SIZES( face ) )
2894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Error  error;
2896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Match_Size( face, req, 0, &strike_index );
2899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
2900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return error;
2901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Select_Size( face, (FT_Int)strike_index );
2903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Request_Metrics( face, req );
2906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Ok;
2908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Set_Char_Size( FT_Face     face,
2915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_F26Dot6  char_width,
2916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_F26Dot6  char_height,
2917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_UInt     horz_resolution,
2918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_UInt     vert_resolution )
2919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Size_RequestRec  req;
2921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !char_width )
2924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      char_width = char_height;
2925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( !char_height )
2926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      char_height = char_width;
2927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !horz_resolution )
2929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      horz_resolution = vert_resolution;
2930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( !vert_resolution )
2931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vert_resolution = horz_resolution;
2932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( char_width  < 1 * 64 )
2934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      char_width  = 1 * 64;
2935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( char_height < 1 * 64 )
2936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      char_height = 1 * 64;
2937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !horz_resolution )
2939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      horz_resolution = vert_resolution = 72;
2940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.type           = FT_SIZE_REQUEST_TYPE_NOMINAL;
2942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.width          = char_width;
2943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.height         = char_height;
2944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.horiResolution = horz_resolution;
2945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.vertResolution = vert_resolution;
2946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Request_Size( face, &req );
2948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Set_Pixel_Sizes( FT_Face  face,
2955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_UInt  pixel_width,
2956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_UInt  pixel_height )
2957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Size_RequestRec  req;
2959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pixel_width == 0 )
2962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pixel_width = pixel_height;
2963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( pixel_height == 0 )
2964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pixel_height = pixel_width;
2965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pixel_width  < 1 )
2967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pixel_width  = 1;
2968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pixel_height < 1 )
2969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pixel_height = 1;
2970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* use `>=' to avoid potential compiler warning on 16bit platforms */
2972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pixel_width  >= 0xFFFFU )
2973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pixel_width  = 0xFFFFU;
2974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( pixel_height >= 0xFFFFU )
2975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pixel_height = 0xFFFFU;
2976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.type           = FT_SIZE_REQUEST_TYPE_NOMINAL;
2978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.width          = pixel_width << 6;
2979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.height         = pixel_height << 6;
2980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.horiResolution = 0;
2981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    req.vertResolution = 0;
2982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Request_Size( face, &req );
2984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
2988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
2990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Kerning( FT_Face     face,
2991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_UInt     left_glyph,
2992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_UInt     right_glyph,
2993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_UInt     kern_mode,
2994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Vector  *akerning )
2995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error = FT_Err_Ok;
2997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Driver  driver;
2998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
3001727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
3002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !akerning )
3004727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
3005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    driver = face->driver;
3007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    akerning->x = 0;
3009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    akerning->y = 0;
3010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( driver->clazz->get_kerning )
3012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = driver->clazz->get_kerning( face,
3014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                          left_glyph,
3015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                          right_glyph,
3016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                          akerning );
3017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !error )
3018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( kern_mode != FT_KERNING_UNSCALED )
3020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
3021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          akerning->x = FT_MulFix( akerning->x, face->size->metrics.x_scale );
3022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          akerning->y = FT_MulFix( akerning->y, face->size->metrics.y_scale );
3023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( kern_mode != FT_KERNING_UNFITTED )
3025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
3026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* we scale down kerning values for small ppem values */
3027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* to avoid that rounding makes them too big.         */
3028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            /* `25' has been determined heuristically.            */
3029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( face->size->metrics.x_ppem < 25 )
3030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              akerning->x = FT_MulDiv( akerning->x,
3031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       face->size->metrics.x_ppem, 25 );
3032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( face->size->metrics.y_ppem < 25 )
3033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              akerning->y = FT_MulDiv( akerning->y,
3034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       face->size->metrics.y_ppem, 25 );
3035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            akerning->x = FT_PIX_ROUND( akerning->x );
3037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            akerning->y = FT_PIX_ROUND( akerning->y );
3038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
3039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
3040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
3044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Track_Kerning( FT_Face    face,
3051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Fixed   point_size,
3052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Int     degree,
3053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Fixed*  akerning )
3054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Service_Kerning  service;
3056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error            error = FT_Err_Ok;
3057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
3060727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
3061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !akerning )
3063727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
3064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FACE_FIND_SERVICE( face, service, KERNING );
3066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !service )
3067727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unimplemented_Feature );
3068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = service->get_track( face,
3070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                point_size,
3071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                degree,
3072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                akerning );
3073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
3075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Select_Charmap( FT_Face      face,
3082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Encoding  encoding )
3083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  cur;
3085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  limit;
3086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
3089727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
3090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( encoding == FT_ENCODING_NONE )
3092727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
3093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* FT_ENCODING_UNICODE is special.  We try to find the `best' Unicode */
3095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* charmap available, i.e., one with UCS-4 characters, if possible.   */
3096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                    */
3097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* This is done by find_unicode_charmap() above, to share code.       */
3098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( encoding == FT_ENCODING_UNICODE )
3099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return find_unicode_charmap( face );
3100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur = face->charmaps;
3102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !cur )
3103727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_CharMap_Handle );
3104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    limit = cur + face->num_charmaps;
3106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; cur < limit; cur++ )
3108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur[0]->encoding == encoding )
3110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3111aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE
3112aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE )
3113aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
3114aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_ERROR(( "FT_Select_Charmap: requested charmap is found (%d), "
3115aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                     "but in too late position to cache\n",
3116aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                     cur - face->charmaps ));
3117aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          continue;
3118aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        }
3119aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
3120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->charmap = cur[0];
3121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return 0;
3122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3125727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_THROW( Invalid_Argument );
3126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Set_Charmap( FT_Face     face,
3133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_CharMap  charmap )
3134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  cur;
3136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CharMap*  limit;
3137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
3140727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
3141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur = face->charmaps;
3143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !cur )
3144727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_CharMap_Handle );
3145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_Get_CMap_Format( charmap ) == 14 )
3146727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
3147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    limit = cur + face->num_charmaps;
3149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; cur < limit; cur++ )
3151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cur[0] == charmap )
3153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3154aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE
3155aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( cur - face->charmaps > FT_MAX_CHARMAP_CACHEABLE )
3156aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
3157aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_ERROR(( "FT_Set_Charmap: requested charmap is found (%d), "
3158aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                     "but in too late position to cache\n",
3159aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                     cur - face->charmaps ));
3160aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          continue;
3161aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        }
3162aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
3163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->charmap = cur[0];
3164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return 0;
3165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3167727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_THROW( Invalid_Argument );
3168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Int )
3174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Charmap_Index( FT_CharMap  charmap )
3175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int  i;
3177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3179aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( !charmap || !charmap->face )
3180aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      return -1;
3181aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
3182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0; i < charmap->face->num_charmaps; i++ )
3183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charmap->face->charmaps[i] == charmap )
3184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
3185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( i < charmap->face->num_charmaps );
3187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3188aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_MAX_CHARMAP_CACHEABLE
3189aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( i > FT_MAX_CHARMAP_CACHEABLE )
3190aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    {
3191aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_ERROR(( "FT_Get_Charmap_Index: requested charmap is found (%d), "
3192aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                 "but in too late position to cache\n",
3193aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                 i ));
3194aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      return -i;
3195aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    }
3196aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
3197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return i;
3198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
3202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_cmap_done_internal( FT_CMap  cmap )
3203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_CMap_Class  clazz  = cmap->clazz;
3205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face        face   = cmap->charmap.face;
3206727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Memory      memory = FT_FACE_MEMORY( face );
3207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->done )
3210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      clazz->done( cmap );
3211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( cmap );
3213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
3217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_CMap_Done( FT_CMap  cmap )
3218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( cmap )
3220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Face    face   = cmap->charmap.face;
3222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Memory  memory = FT_FACE_MEMORY( face );
3223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Error   error;
3224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int     i, j;
3225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( i = 0; i < face->num_charmaps; i++ )
3228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( (FT_CMap)face->charmaps[i] == cmap )
3230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
3231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_CharMap  last_charmap = face->charmaps[face->num_charmaps - 1];
3232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( FT_RENEW_ARRAY( face->charmaps,
3235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               face->num_charmaps,
3236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               face->num_charmaps - 1 ) )
3237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            return;
3238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* remove it from our list of charmaps */
3240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( j = i + 1; j < face->num_charmaps; j++ )
3241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
3242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( j == face->num_charmaps - 1 )
3243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              face->charmaps[j - 1] = last_charmap;
3244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            else
3245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              face->charmaps[j - 1] = face->charmaps[j];
3246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
3247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          face->num_charmaps--;
3249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( (FT_CMap)face->charmap == cmap )
3251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            face->charmap = NULL;
3252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ft_cmap_done_internal( cmap );
3254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
3256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
3257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
3263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_CMap_New( FT_CMap_Class  clazz,
3264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Pointer     init_data,
3265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_CharMap     charmap,
3266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_CMap       *acmap )
3267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error = FT_Err_Ok;
3269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face    face;
3270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory;
3271aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_CMap    cmap = NULL;
3272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz == NULL || charmap == NULL || charmap->face == NULL )
3275727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
3276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face   = charmap->face;
3278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = FT_FACE_MEMORY( face );
3279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_ALLOC( cmap, clazz->size ) )
3281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cmap->charmap = *charmap;
3283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cmap->clazz   = clazz;
3284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( clazz->init )
3286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = clazz->init( cmap, init_data );
3288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
3289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
3290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* add it to our list of charmaps */
3293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_RENEW_ARRAY( face->charmaps,
3294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           face->num_charmaps,
3295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           face->num_charmaps + 1 ) )
3296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
3297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->charmaps[face->num_charmaps++] = (FT_CharMap)cmap;
3299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
3302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( acmap )
3303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *acmap = cmap;
3304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
3306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
3308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_cmap_done_internal( cmap );
3309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cmap = NULL;
3310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
3311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_UInt )
3317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Char_Index( FT_Face   face,
3318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_ULong  charcode )
3319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  result = 0;
3321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face && face->charmap )
3324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CMap  cmap = FT_CMAP( face->charmap );
3326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3328295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      if ( charcode > 0xFFFFFFFFUL )
3329295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      {
3330295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
3331295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3332295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      }
3333295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      result = cmap->clazz->char_index( cmap, (FT_UInt32)charcode );
3334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3335aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    return result;
3336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_ULong )
3342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_First_Char( FT_Face   face,
3343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_UInt  *agindex )
3344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong  result = 0;
3346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt   gindex = 0;
3347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3349aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( face && face->charmap && face->num_glyphs )
3350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gindex = FT_Get_Char_Index( face, 0 );
3352aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( gindex == 0 || gindex >= (FT_UInt)face->num_glyphs )
3353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = FT_Get_Next_Char( face, 0, &gindex );
3354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3356aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( agindex )
3357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *agindex = gindex;
3358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_ULong )
3366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Next_Char( FT_Face   face,
3367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_ULong  charcode,
3368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_UInt  *agindex )
3369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong  result = 0;
3371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt   gindex = 0;
3372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3374aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( face && face->charmap && face->num_glyphs )
3375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt32  code = (FT_UInt32)charcode;
3377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CMap    cmap = FT_CMAP( face->charmap );
3378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3380aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      do {
3381aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        gindex = cmap->clazz->char_next( cmap, &code );
3382aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      } while ( gindex >= (FT_UInt)face->num_glyphs );
3383aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
3384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      result = ( gindex == 0 ) ? 0 : code;
3385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( agindex )
3388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *agindex = gindex;
3389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_UInt )
3397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Face_GetCharVariantIndex( FT_Face   face,
3398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_ULong  charcode,
3399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               FT_ULong  variantSelector )
3400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  result = 0;
3402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face && face->charmap &&
3405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->charmap->encoding == FT_ENCODING_UNICODE )
3406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CharMap  charmap = find_variant_selector_charmap( face );
3408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CMap     ucmap = FT_CMAP( face->charmap );
3409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charmap != NULL )
3412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_CMap  vcmap = FT_CMAP( charmap );
3414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3416295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( charcode > 0xFFFFFFFFUL )
3417295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
3418295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
3419295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3420295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
3421295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( variantSelector > 0xFFFFFFFFUL )
3422295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
3423295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
3424295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
3425295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
3426295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
3427295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        result = vcmap->clazz->char_var_index( vcmap, ucmap,
3428295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                               (FT_UInt32)charcode,
3429295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                               (FT_UInt32)variantSelector );
3430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Int )
3440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Face_GetCharVariantIsDefault( FT_Face   face,
3441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   FT_ULong  charcode,
3442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   FT_ULong  variantSelector )
3443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int  result = -1;
3445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face )
3448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CharMap  charmap = find_variant_selector_charmap( face );
3450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charmap != NULL )
3453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_CMap  vcmap = FT_CMAP( charmap );
3455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3457295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( charcode > 0xFFFFFFFFUL )
3458295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
3459295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
3460295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3461295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
3462295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( variantSelector > 0xFFFFFFFFUL )
3463295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
3464295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
3465295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
3466295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
3467295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
3468295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        result = vcmap->clazz->char_var_default( vcmap,
3469295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                                 (FT_UInt32)charcode,
3470295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                                 (FT_UInt32)variantSelector );
3471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_UInt32* )
3481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Face_GetVariantSelectors( FT_Face  face )
3482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  *result = NULL;
3484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face )
3487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CharMap  charmap = find_variant_selector_charmap( face );
3489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charmap != NULL )
3492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_CMap    vcmap  = FT_CMAP( charmap );
3494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Memory  memory = FT_FACE_MEMORY( face );
3495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = vcmap->clazz->variant_list( vcmap, memory );
3498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_UInt32* )
3508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Face_GetVariantsOfChar( FT_Face   face,
3509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             FT_ULong  charcode )
3510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  *result = NULL;
3512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face )
3515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CharMap  charmap = find_variant_selector_charmap( face );
3517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charmap != NULL )
3520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_CMap    vcmap  = FT_CMAP( charmap );
3522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Memory  memory = FT_FACE_MEMORY( face );
3523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3525295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( charcode > 0xFFFFFFFFUL )
3526295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
3527295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( "FT_Get_Char_Index: too large charcode" ));
3528295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( " 0x%x is truncated\n", charcode ));
3529295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
3530295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
3531295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        result = vcmap->clazz->charvariant_list( vcmap, memory,
3532295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                                 (FT_UInt32)charcode );
3533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_UInt32* )
3542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Face_GetCharsOfVariant( FT_Face   face,
3543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             FT_ULong  variantSelector )
3544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  *result = NULL;
3546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face )
3549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_CharMap  charmap = find_variant_selector_charmap( face );
3551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( charmap != NULL )
3554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_CMap    vcmap  = FT_CMAP( charmap );
3556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Memory  memory = FT_FACE_MEMORY( face );
3557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3559295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( variantSelector > 0xFFFFFFFFUL )
3560295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
3561295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( "FT_Get_Char_Index: too large variantSelector" ));
3562295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE1(( " 0x%x is truncated\n", variantSelector ));
3563295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
3564295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
3565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = vcmap->clazz->variantchar_list( vcmap, memory,
3566295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                                 (FT_UInt32)variantSelector );
3567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_UInt )
3577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Name_Index( FT_Face     face,
3578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_String*  glyph_name )
3579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  result = 0;
3581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face && FT_HAS_GLYPH_NAMES( face ) )
3584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Service_GlyphDict  service;
3586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FACE_LOOKUP_SERVICE( face,
3589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              service,
3590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              GLYPH_DICT );
3591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( service && service->name_index )
3593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = service->name_index( face, glyph_name );
3594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Glyph_Name( FT_Face     face,
3604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_UInt     glyph_index,
3605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Pointer  buffer,
3606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_UInt     buffer_max )
3607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3608727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error  error = FT_ERR( Invalid_Argument );
3609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* clean up buffer */
3612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( buffer && buffer_max > 0 )
3613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ((FT_Byte*)buffer)[0] = 0;
3614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face                                     &&
3616295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner         (FT_Long)glyph_index <= face->num_glyphs &&
3617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_HAS_GLYPH_NAMES( face )               )
3618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Service_GlyphDict  service;
3620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FACE_LOOKUP_SERVICE( face,
3623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              service,
3624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              GLYPH_DICT );
3625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( service && service->get_name )
3627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = service->get_name( face, glyph_index, buffer, buffer_max );
3628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
3631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
3635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( const char* )
3637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Postscript_Name( FT_Face  face )
3638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const char*  result = NULL;
3640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
3643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
3644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !result )
3646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Service_PsFontName  service;
3648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FACE_LOOKUP_SERVICE( face,
3651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              service,
3652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              POSTSCRIPT_FONT_NAME );
3653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( service && service->get_ps_font_name )
3655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = service->get_ps_font_name( face );
3656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
3659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in tttables.h */
3664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void* )
3666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Sfnt_Table( FT_Face      face,
3667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Sfnt_Tag  tag )
3668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    void*                  table = 0;
3670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Service_SFNT_Table  service;
3671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face && FT_IS_SFNT( face ) )
3674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
3676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( service != NULL )
3677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        table = service->get_table( face, tag );
3678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return table;
3681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in tttables.h */
3685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Load_Sfnt_Table( FT_Face    face,
3688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ULong   tag,
3689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Long    offset,
3690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Byte*   buffer,
3691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ULong*  length )
3692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Service_SFNT_Table  service;
3694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face || !FT_IS_SFNT( face ) )
3697727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
3698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
3700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( service == NULL )
3701727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unimplemented_Feature );
3702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return service->load_table( face, tag, offset, buffer, length );
3704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in tttables.h */
3708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Sfnt_Table_Info( FT_Face    face,
3711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_UInt    table_index,
3712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ULong  *tag,
3713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ULong  *length )
3714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Service_SFNT_Table  service;
3716295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_ULong               offset;
3717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face || !FT_IS_SFNT( face ) )
3720727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
3721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
3723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( service == NULL )
3724727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unimplemented_Feature );
3725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3726295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    return service->table_info( face, table_index, tag, &offset, length );
3727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in tttables.h */
3731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_ULong )
3733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_CMap_Language_ID( FT_CharMap  charmap )
3734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Service_TTCMaps  service;
3736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face             face;
3737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_CMapInfo         cmap_info;
3738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !charmap || !charmap->face )
3741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
3742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face = charmap->face;
3744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FACE_FIND_SERVICE( face, service, TT_CMAP );
3745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( service == NULL )
3746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
3747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( service->get_cmap_info( charmap, &cmap_info ))
3748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
3749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return cmap_info.language;
3751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in tttables.h */
3755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Long )
3757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_CMap_Format( FT_CharMap  charmap )
3758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Service_TTCMaps  service;
3760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face             face;
3761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_CMapInfo         cmap_info;
3762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !charmap || !charmap->face )
3765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return -1;
3766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face = charmap->face;
3768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FACE_FIND_SERVICE( face, service, TT_CMAP );
3769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( service == NULL )
3770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return -1;
3771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( service->get_cmap_info( charmap, &cmap_info ))
3772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return -1;
3773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return cmap_info.format;
3775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftsizes.h */
3779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Activate_Size( FT_Size  size )
3782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face  face;
3784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( size == NULL )
3787727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
3788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face = size->face;
3790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face == NULL || face->driver == NULL )
3791727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
3792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* we don't need anything more complex than that; all size objects */
3794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* are already listed by the face                                  */
3795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->size = size;
3796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Ok;
3798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
3802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
3803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
3804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
3805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
3806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                        R E N D E R E R S                        ****/
3807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
3808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
3809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
3810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
3811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
3812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* lookup a renderer by glyph format in the library's list */
3814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Renderer )
3815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Lookup_Renderer( FT_Library       library,
3816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Glyph_Format  format,
3817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_ListNode*     node )
3818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ListNode  cur;
3820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Renderer  result = 0;
3821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
3824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
3825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur = library->renderers.head;
3827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( node )
3829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( *node )
3831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cur = (*node)->next;
3832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *node = 0;
3833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( cur )
3836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Renderer  renderer = FT_RENDERER( cur->data );
3838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( renderer->glyph_format == format )
3841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( node )
3843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *node = cur;
3844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = renderer;
3846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
3847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cur = cur->next;
3849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
3852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Renderer
3857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_lookup_glyph_renderer( FT_GlyphSlot  slot )
3858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face      face    = slot->face;
3860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Library   library = FT_FACE_LIBRARY( face );
3861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Renderer  result  = library->cur_renderer;
3862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !result || result->glyph_format != slot->format )
3865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      result = FT_Lookup_Renderer( library, slot->format, 0 );
3866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
3868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
3872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_set_current_renderer( FT_Library  library )
3873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Renderer  renderer;
3875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    renderer = FT_Lookup_Renderer( library, FT_GLYPH_FORMAT_OUTLINE, 0 );
3878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library->cur_renderer = renderer;
3879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
3883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_add_renderer( FT_Module  module )
3884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Library   library = module->library;
3886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory    memory  = library->memory;
3887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error;
3888aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_ListNode  node    = NULL;
3889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( node ) )
3892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
3893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Renderer         render = FT_RENDERER( module );
3896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Renderer_Class*  clazz  = (FT_Renderer_Class*)module->clazz;
3897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      render->clazz        = clazz;
3900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      render->glyph_format = clazz->glyph_format;
3901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* allocate raster object if needed */
3903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
3904aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich           clazz->raster_class->raster_new                )
3905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
3906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = clazz->raster_class->raster_new( memory, &render->raster );
3907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
3908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
3909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        render->raster_render = clazz->raster_class->raster_render;
3911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        render->render        = clazz->render_glyph;
3912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
3913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* add to list */
3915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      node->data = module;
3916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_List_Add( &library->renderers, node );
3917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_set_current_renderer( library );
3919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
3922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
3923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( node );
3924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
3926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
3927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
3931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_remove_renderer( FT_Module  module )
3932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Library   library = module->library;
3934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory    memory  = library->memory;
3935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ListNode  node;
3936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node = FT_List_Find( &library->renderers, module );
3939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( node )
3940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Renderer  render = FT_RENDERER( module );
3942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* release raster object, if any */
3945aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( render->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
3946aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich           render->raster                                         )
3947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        render->clazz->raster_class->raster_done( render->raster );
3948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* remove from list */
3950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_List_Remove( &library->renderers, node );
3951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_FREE( node );
3952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_set_current_renderer( library );
3954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftrender.h */
3959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Renderer )
3961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Renderer( FT_Library       library,
3962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Glyph_Format  format )
3963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `library' delayed to FT_Lookup_Renderer() */
3965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Lookup_Renderer( library, format, 0 );
3967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
3968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftrender.h */
3971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
3973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Set_Renderer( FT_Library     library,
3974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Renderer    renderer,
3975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_UInt        num_params,
3976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Parameter*  parameters )
3977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
3978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ListNode  node;
3979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error = FT_Err_Ok;
3980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
3983727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Library_Handle );
3984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !renderer )
3986727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
3987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    node = FT_List_Find( &library->renderers, renderer );
3989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !node )
3990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
3991727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Invalid_Argument );
3992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
3993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
3994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_List_Up( &library->renderers, node );
3996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( renderer->glyph_format == FT_GLYPH_FORMAT_OUTLINE )
3998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      library->cur_renderer = renderer;
3999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( num_params > 0 )
4001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Renderer_SetModeFunc  set_mode = renderer->clazz->set_mode;
4003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; num_params > 0; num_params-- )
4006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = set_mode( renderer, parameters->tag, parameters->data );
4008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
4009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
4010aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        parameters++;
4011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
4015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
4016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Error )
4020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Render_Glyph_Internal( FT_Library      library,
4021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_GlyphSlot    slot,
4022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            FT_Render_Mode  render_mode )
4023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error = FT_Err_Ok;
4025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Renderer  renderer;
4026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if it is already a bitmap, no need to do anything */
4029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    switch ( slot->format )
4030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_GLYPH_FORMAT_BITMAP:   /* already a bitmap, don't do anything */
4032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
4033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    default:
4035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ListNode  node   = 0;
4037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Bool      update = 0;
4038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* small shortcut for the very common case */
4041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
4042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
4043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          renderer = library->cur_renderer;
4044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          node     = library->renderers.head;
4045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
4046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
4047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          renderer = FT_Lookup_Renderer( library, slot->format, &node );
4048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4049727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_ERR( Unimplemented_Feature );
4050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        while ( renderer )
4051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
4052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          error = renderer->render( renderer, slot, render_mode, NULL );
4053727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          if ( !error                                   ||
4054727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease               FT_ERR_NEQ( error, Cannot_Render_Glyph ) )
4055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            break;
4056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* FT_Err_Cannot_Render_Glyph is returned if the render mode   */
4058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* is unsupported by the current renderer for this glyph image */
4059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* format.                                                     */
4060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* now, look for another renderer that supports the same */
4062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* format.                                               */
4063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          renderer = FT_Lookup_Renderer( library, slot->format, &node );
4064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          update   = 1;
4065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
4066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* if we changed the current renderer for the glyph image format */
4068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* we need to select it as the next current one                  */
4069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !error && update && renderer )
4070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Set_Renderer( library, renderer, 0, 0 );
4071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4074727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef FT_DEBUG_LEVEL_TRACE
4075727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4076727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#undef  FT_COMPONENT
4077727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define FT_COMPONENT  trace_bitmap
4078727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4079727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* we convert to a single bitmap format for computing the checksum */
4080727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
4081727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Bitmap  bitmap;
4082727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Error   err;
4083727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4084727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4085727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Bitmap_New( &bitmap );
4086727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4087727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      err = FT_Bitmap_Convert( library, &slot->bitmap, &bitmap, 1 );
4088727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( !err )
4089727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
4090727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        MD5_CTX        ctx;
4091727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        unsigned char  md5[16];
4092727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        int            i;
4093727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4094727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4095727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        MD5_Init( &ctx);
4096727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        MD5_Update( &ctx, bitmap.buffer, bitmap.rows * bitmap.pitch );
4097727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        MD5_Final( md5, &ctx );
4098727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4099727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_TRACE3(( "MD5 checksum for %dx%d bitmap:\n"
4100727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                    "  ",
4101727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                    bitmap.rows, bitmap.pitch ));
4102727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        for ( i = 0; i < 16; i++ )
4103727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_TRACE3(( "%02X", md5[i] ));
4104727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_TRACE3(( "\n" ));
4105727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
4106727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4107727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Bitmap_Done( library, &bitmap );
4108727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
4109727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4110727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#undef  FT_COMPONENT
4111727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define FT_COMPONENT  trace_objs
4112727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4113727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* FT_DEBUG_LEVEL_TRACE */
4114727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
4116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
4120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
4122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Render_Glyph( FT_GlyphSlot    slot,
4123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Render_Mode  render_mode )
4124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Library  library;
4126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4128aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( !slot || !slot->face )
4129727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
4130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library = FT_FACE_LIBRARY( slot->face );
4132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Render_Glyph_Internal( library, slot, render_mode );
4134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                         M O D U L E S                           ****/
4143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
4152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
4153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Destroy_Module                                                     */
4154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
4155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
4156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Destroys a given module object.  For drivers, this also destroys   */
4157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    all child faces.                                                   */
4158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
4159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <InOut>                                                               */
416041371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier  /*    module :: A handle to the target driver object.                    */
4161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
4162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Note>                                                                */
416341371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier  /*    The driver _must_ be LOCKED!                                       */
4164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
4165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
4166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Destroy_Module( FT_Module  module )
4167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory         memory  = module->memory;
4169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module_Class*  clazz   = module->clazz;
4170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Library        library = module->library;
4171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( library && library->auto_hinter == module )
4174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      library->auto_hinter = 0;
4175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if the module is a renderer */
4177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_RENDERER( module ) )
4178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_remove_renderer( module );
4179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if the module is a font driver, add some steps */
4181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_DRIVER( module ) )
4182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      Destroy_Driver( FT_DRIVER( module ) );
4183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* finalize the module object */
4185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->module_done )
4186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      clazz->module_done( module );
4187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* discard it */
4189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( module );
4190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
4196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Add_Module( FT_Library              library,
4197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const FT_Module_Class*  clazz )
4198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
4200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory;
4201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module  module;
4202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt    nn;
4203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FREETYPE_VER_FIXED  ( ( (FT_Long)FREETYPE_MAJOR << 16 ) | \
4206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                FREETYPE_MINOR                  )
4207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
4209727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Library_Handle );
4210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !clazz )
4212727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
4213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check freetype version */
4215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->module_requires > FREETYPE_VER_FIXED )
4216727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Version );
4217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* look for a module with the same name in the library's table */
4219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( nn = 0; nn < library->num_modules; nn++ )
4220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      module = library->modules[nn];
4222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ft_strcmp( module->clazz->module_name, clazz->module_name ) == 0 )
4223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* this installed module has the same name, compare their versions */
4225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( clazz->module_version <= module->clazz->module_version )
4226727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          return FT_THROW( Lower_Module_Version );
4227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* remove the module from our list, then exit the loop to replace */
4229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* it by our new version..                                        */
4230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Remove_Module( library, module );
4231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
4232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = library->memory;
4236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error  = FT_Err_Ok;
4237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( library->num_modules >= FT_MAX_MODULES )
4239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4240727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Too_Many_Drivers );
4241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
4242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* allocate module object */
4245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( module, clazz->module_size ) )
4246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
4247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* base initialization */
4249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    module->library = library;
4250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    module->memory  = memory;
4251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    module->clazz   = (FT_Module_Class*)clazz;
4252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check whether the module is a renderer - this must be performed */
4254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* before the normal module initialization                         */
4255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_RENDERER( module ) )
4256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* add to the renderers list */
4258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = ft_add_renderer( module );
4259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
4260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
4261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* is the module a auto-hinter? */
4264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_HINTER( module ) )
4265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      library->auto_hinter = module;
4266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if the module is a font driver */
4268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_DRIVER( module ) )
4269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* allocate glyph loader if needed */
4271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Driver  driver = FT_DRIVER( module );
4272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      driver->clazz = (FT_Driver_Class)module->clazz;
4275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_DRIVER_USES_OUTLINES( driver ) )
4276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = FT_GlyphLoader_New( memory, &driver->glyph_loader );
4278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
4279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Fail;
4280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( clazz->module_init )
4284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = clazz->module_init( module );
4286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
4287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
4288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* add module to the library's table */
4291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library->modules[library->num_modules++] = module;
4292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
4294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
4295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
4297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_DRIVER( module ) )
4298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Driver  driver = FT_DRIVER( module );
4300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_DRIVER_USES_OUTLINES( driver ) )
4303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_GlyphLoader_Done( driver->glyph_loader );
4304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_MODULE_IS_RENDERER( module ) )
4307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Renderer  renderer = FT_RENDERER( module );
4309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4311aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      if ( renderer->clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE &&
4312aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich           renderer->raster                                         )
4313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        renderer->clazz->raster_class->raster_done( renderer->raster );
4314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( module );
4317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Exit;
4318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Module )
4324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Module( FT_Library   library,
4325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const char*  module_name )
4326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module   result = 0;
4328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module*  cur;
4329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module*  limit;
4330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library || !module_name )
4333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return result;
4334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cur   = library->modules;
4336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    limit = cur + library->num_modules;
4337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; cur < limit; cur++ )
4339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ft_strcmp( cur[0]->clazz->module_name, module_name ) == 0 )
4340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = cur[0];
4342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
4343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
4346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftobjs.h */
4350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( const void* )
4352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Module_Interface( FT_Library   library,
4353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           const char*  mod_name )
4354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Module  module;
4356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* test for valid `library' delayed to FT_Get_Module() */
4359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    module = FT_Get_Module( library, mod_name );
4361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return module ? module->clazz->module_interface : 0;
4363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Pointer )
4367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_module_get_service( FT_Module    module,
4368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         const char*  service_id )
4369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pointer  result = NULL;
4371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4372727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( module )
4374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ASSERT( module->clazz && module->clazz->get_interface );
4376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4377727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      /* first, look for the service in the module */
4378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( module->clazz->get_interface )
4379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = module->clazz->get_interface( module, service_id );
4380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( result == NULL )
4382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4383727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* we didn't find it, look in all other modules then */
4384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Library  library = module->library;
4385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Module*  cur     = library->modules;
4386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Module*  limit   = cur + library->num_modules;
4387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
438841371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier
4389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( ; cur < limit; cur++ )
4390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
4391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( cur[0] != module )
4392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
4393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_ASSERT( cur[0]->clazz );
4394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( cur[0]->clazz->get_interface )
4396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
4397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              result = cur[0]->clazz->get_interface( cur[0], service_id );
4398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( result != NULL )
4399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                break;
4400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
4401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
4402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
4403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
4407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
4413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Remove_Module( FT_Library  library,
4414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Module   module )
4415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* try to find the module from the table, then remove it from there */
4417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
4419727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Library_Handle );
4420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( module )
4422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Module*  cur   = library->modules;
4424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Module*  limit = cur + library->num_modules;
4425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; cur < limit; cur++ )
4428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( cur[0] == module )
4430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
4431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* remove it from the table */
4432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          library->num_modules--;
4433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          limit--;
4434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          while ( cur < limit )
4435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
4436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            cur[0] = cur[1];
4437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            cur++;
4438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
4439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          limit[0] = 0;
4440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* destroy the module */
4442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          Destroy_Module( module );
4443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return FT_Err_Ok;
4445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
4446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4448727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_THROW( Invalid_Driver_Handle );
4449727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
4450727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4451727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4452727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_Error
4453727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  ft_property_do( FT_Library        library,
4454727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                  const FT_String*  module_name,
4455727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                  const FT_String*  property_name,
4456727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                  void*             value,
4457727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                  FT_Bool           set )
4458727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
4459727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Module*           cur;
4460727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Module*           limit;
4461727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Module_Interface  interface;
4462727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4463727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Service_Properties  service;
4464727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4465727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef FT_DEBUG_LEVEL_ERROR
4466727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    const FT_String*  set_name  = "FT_Property_Set";
4467727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    const FT_String*  get_name  = "FT_Property_Get";
4468727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    const FT_String*  func_name = set ? set_name : get_name;
4469727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif
4470727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4471727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Bool  missing_func;
4472727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4473727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4474727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( !library )
4475727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Library_Handle );
4476727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4477727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( !module_name || !property_name || !value )
4478727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
4479727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4480727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cur   = library->modules;
4481727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    limit = cur + library->num_modules;
4482727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4483727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* search module */
4484727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    for ( ; cur < limit; cur++ )
4485727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( !ft_strcmp( cur[0]->clazz->module_name, module_name ) )
4486727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        break;
4487727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4488727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( cur == limit )
4489727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
4490727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_ERROR(( "%s: can't find module `%s'\n",
4491727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                 func_name, module_name ));
4492727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Missing_Module );
4493727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
4494727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4495727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* check whether we have a service interface */
4496727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( !cur[0]->clazz->get_interface )
4497727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
4498727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_ERROR(( "%s: module `%s' doesn't support properties\n",
4499727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                 func_name, module_name ));
4500727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unimplemented_Feature );
4501727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
4502727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4503727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* search property service */
4504727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    interface = cur[0]->clazz->get_interface( cur[0],
4505727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                              FT_SERVICE_ID_PROPERTIES );
4506727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( !interface )
4507727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
4508727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_ERROR(( "%s: module `%s' doesn't support properties\n",
4509727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                 func_name, module_name ));
4510727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unimplemented_Feature );
4511727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
4512727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4513727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    service = (FT_Service_Properties)interface;
4514727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4515727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( set )
4516727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      missing_func = !service->set_property;
4517727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    else
4518727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      missing_func = !service->get_property;
4519727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4520727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( missing_func )
4521727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
4522727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_ERROR(( "%s: property service of module `%s' is broken\n",
4523727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                 func_name, module_name ));
4524727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unimplemented_Feature );
4525727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
4526727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4527727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return set ? service->set_property( cur[0], property_name, value )
4528727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease               : service->get_property( cur[0], property_name, value );
4529727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
4530727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4531727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4532727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* documentation is in ftmodapi.h */
4533727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4534727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_EXPORT_DEF( FT_Error )
4535727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_Property_Set( FT_Library        library,
4536727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   const FT_String*  module_name,
4537727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   const FT_String*  property_name,
4538727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   const void*       value )
4539727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
4540727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return ft_property_do( library,
4541727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                           module_name,
4542727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                           property_name,
4543727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                           (void*)value,
4544727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                           TRUE );
4545727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
4546727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4547727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4548727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* documentation is in ftmodapi.h */
4549727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
4550727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_EXPORT_DEF( FT_Error )
4551727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_Property_Get( FT_Library        library,
4552727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   const FT_String*  module_name,
4553727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   const FT_String*  property_name,
4554727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   void*             value )
4555727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
4556727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return ft_property_do( library,
4557727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                           module_name,
4558727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                           property_name,
4559727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                           value,
4560727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                           FALSE );
4561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                         L I B R A R Y                           ****/
4570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /****                                                                 ****/
4572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
4575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
4580aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  FT_Reference_Library( FT_Library  library )
4581aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  {
4582aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    library->refcount++;
4583aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4584aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    return FT_Err_Ok;
4585aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  }
4586aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4587aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4588aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  /* documentation is in ftmodapi.h */
4589aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4590aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  FT_EXPORT_DEF( FT_Error )
4591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_New_Library( FT_Memory    memory,
4592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Library  *alibrary )
4593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4594aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Library  library = NULL;
4595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error    error;
4596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !memory )
4599727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
4600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_DEBUG_LEVEL_ERROR
4602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* init debugging support */
4603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_debug_init();
4604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
4605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* first of all, allocate the library object */
4607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_NEW( library ) )
4608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
4609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library->memory = memory;
4611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4612295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifdef FT_CONFIG_OPTION_PIC
4613295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* initialize position independent code containers */
4614295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    error = ft_pic_container_init( library );
4615295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( error )
4616295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      goto Fail;
4617295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
4618295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
4619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* allocate the render pool */
4620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library->raster_pool_size = FT_RENDER_POOL_SIZE;
4621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if FT_RENDER_POOL_SIZE > 0
4622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_ALLOC( library->raster_pool, FT_RENDER_POOL_SIZE ) )
4623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
4624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
4625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4626295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    library->version_major = FREETYPE_MAJOR;
4627295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    library->version_minor = FREETYPE_MINOR;
4628295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    library->version_patch = FREETYPE_PATCH;
4629295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
4630aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    library->refcount = 1;
4631aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* That's ok now */
4633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *alibrary = library;
4634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Ok;
4636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
4638295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifdef FT_CONFIG_OPTION_PIC
4639295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    ft_pic_container_destroy( library );
4640295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
4641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( library );
4642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
4643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
4647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
4649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Library_Version( FT_Library   library,
4650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Int      *amajor,
4651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Int      *aminor,
4652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Int      *apatch )
4653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int  major = 0;
4655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int  minor = 0;
4656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int  patch = 0;
4657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( library )
4660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      major = library->version_major;
4662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      minor = library->version_minor;
4663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      patch = library->version_patch;
4664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( amajor )
4667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *amajor = major;
4668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( aminor )
4670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *aminor = minor;
4671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( apatch )
4673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *apatch = patch;
4674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
4680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Done_Library( FT_Library  library )
4681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory;
4683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !library )
4686727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Library_Handle );
4687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4688aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    library->refcount--;
4689aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( library->refcount > 0 )
4690aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      goto Exit;
4691aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    memory = library->memory;
4693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4694aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    /*
4695aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     * Close all faces in the library.  If we don't do this, we can have
4696aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     * some subtle memory leaks.
4697aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     *
4698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     * Example:
4699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *
4700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  - the cff font driver uses the pshinter module in cff_size_done
4701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *  - if the pshinter module is destroyed before the cff font driver,
4702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *    opened FT_Face objects managed by the driver are not properly
4703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     *    destroyed, resulting in a memory leak
4704aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     *
4705aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     * Some faces are dependent on other faces, like Type42 faces that
4706aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     * depend on TrueType faces synthesized internally.
4707aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     *
4708aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich     * The order of drivers should be specified in driver_name[].
4709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     */
4710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4711aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_UInt      m, n;
4712aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      const char*  driver_name[] = { "type42", NULL };
4713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4715aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      for ( m = 0;
4716aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            m < sizeof ( driver_name ) / sizeof ( driver_name[0] );
4717aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            m++ )
4718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4719aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        for ( n = 0; n < library->num_modules; n++ )
4720aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
4721aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_Module    module      = library->modules[n];
4722aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          const char*  module_name = module->clazz->module_name;
4723aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_List      faces;
4724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4726aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          if ( driver_name[m]                                &&
4727aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich               ft_strcmp( module_name, driver_name[m] ) != 0 )
4728aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            continue;
4729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4730aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          if ( ( module->clazz->module_flags & FT_MODULE_FONT_DRIVER ) == 0 )
4731aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            continue;
4732aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4733aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_TRACE7(( "FT_Done_Library: close faces for %s\n", module_name ));
4734aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4735aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          faces = &FT_DRIVER( module )->faces_list;
4736aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          while ( faces->head )
4737aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          {
4738aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            FT_Done_Face( FT_FACE( faces->head->data ) );
4739aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich            if ( faces->head )
4740aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich              FT_TRACE0(( "FT_Done_Library: failed to free some faces\n" ));
4741aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          }
474277f63d23f7d380b0ff02c18fd6a154ab9063128aDavid 'Digit' Turner        }
4743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Close all other modules in the library */
4747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 1
4748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* XXX Modules are removed in the reversed order so that  */
4749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* type42 module is removed before truetype module.  This */
4750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* avoids double free in some occasions.  It is a hack.   */
4751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( library->num_modules > 0 )
4752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Remove_Module( library,
4753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        library->modules[library->num_modules - 1] );
4754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
4755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt  n;
4757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( n = 0; n < library->num_modules; n++ )
4760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Module  module = library->modules[n];
4762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( module )
4765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
4766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          Destroy_Module( module );
4767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          library->modules[n] = 0;
4768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
4769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
4772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Destroy raster objects */
4774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( library->raster_pool );
4775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    library->raster_pool_size = 0;
4776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4777295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifdef FT_CONFIG_OPTION_PIC
4778295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* Destroy pic container contents */
4779295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    ft_pic_container_destroy( library );
4780295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
4781295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
4782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( library );
4783aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4784aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  Exit:
4785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Err_Ok;
4786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
4792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Set_Debug_Hook( FT_Library         library,
4793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_UInt            hook_index,
4794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_DebugHook_Func  debug_hook )
4795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( library && debug_hook &&
4797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         hook_index <
4798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           ( sizeof ( library->debug_hooks ) / sizeof ( void* ) ) )
4799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      library->debug_hooks[hook_index] = debug_hook;
4800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftmodapi.h */
4804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_TrueTypeEngineType )
4806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_TrueType_Engine_Type( FT_Library  library )
4807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TrueTypeEngineType  result = FT_TRUETYPE_ENGINE_TYPE_NONE;
4809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( library )
4812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Module  module = FT_Get_Module( library, "truetype" );
4814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( module )
4817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
4818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Service_TrueTypeEngine  service;
4819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        service = (FT_Service_TrueTypeEngine)
4822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    ft_module_get_service( module,
4823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           FT_SERVICE_ID_TRUETYPE_ENGINE );
4824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( service )
4825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          result = service->engine_type;
4826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
4827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return result;
4830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4833aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  /* documentation is in freetype.h */
4834aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
4835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
4836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_SubGlyph_Info( FT_GlyphSlot  glyph,
4837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_UInt       sub_index,
4838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Int       *p_index,
4839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_UInt      *p_flags,
4840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Int       *p_arg1,
4841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Int       *p_arg2,
4842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Matrix    *p_transform )
4843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
4844727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error  error = FT_ERR( Invalid_Argument );
4845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4847aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( glyph                                      &&
4848aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich         glyph->subglyphs                           &&
4849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         glyph->format == FT_GLYPH_FORMAT_COMPOSITE &&
4850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         sub_index < glyph->num_subglyphs           )
4851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_SubGlyph  subg = glyph->subglyphs + sub_index;
4853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *p_index     = subg->index;
4856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *p_flags     = subg->flags;
4857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *p_arg1      = subg->arg1;
4858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *p_arg2      = subg->arg2;
4859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *p_transform = subg->transform;
4860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
4861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
4863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
4864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
4867