ttgload.c revision fb6b5b10aaa74b8c8974714b41bac35bdd1c772d
1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  ttgload.c                                                              */
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*    TrueType Glyph Loader (body).                                        */
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
7fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki/*  Copyright 1996-2015 by                                                 */
8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  This file is part of the FreeType project, and may only be used,       */
11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  modified, and distributed under the terms of the FreeType project      */
12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  this file you indicate that you have read the license and              */
14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  understand and accept it fully.                                        */
15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_CALC_H
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_STREAM_H
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_SFNT_H
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_TRUETYPE_TAGS_H
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_OUTLINE_H
26727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include FT_TRUETYPE_DRIVER_H
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ttgload.h"
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ttpload.h"
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ttgxvar.h"
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "tterrors.h"
36727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "ttsubpix.h"
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* messages during execution.                                            */
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_ttgload
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
51aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  /* Composite glyph flags.                                                */
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ARGS_ARE_WORDS             0x0001
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ARGS_ARE_XY_VALUES         0x0002
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ROUND_XY_TO_GRID           0x0004
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define WE_HAVE_A_SCALE            0x0008
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* reserved                        0x0010 */
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define MORE_COMPONENTS            0x0020
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define WE_HAVE_AN_XY_SCALE        0x0040
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define WE_HAVE_A_2X2              0x0080
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define WE_HAVE_INSTR              0x0100
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define USE_MY_METRICS             0x0200
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define OVERLAP_COMPOUND           0x0400
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define SCALED_COMPONENT_OFFSET    0x0800
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define UNSCALED_COMPONENT_OFFSET  0x1000
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
70aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  /* Return the horizontal metrics in font units for a given glyph.        */
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
72295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  FT_LOCAL_DEF( void )
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  TT_Get_HMetrics( TT_Face     face,
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_UInt     idx,
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Short*   lsb,
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_UShort*  aw )
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, idx, lsb, aw );
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
80295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_TRACE5(( "  advance width (font units): %d\n", *aw ));
81295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_TRACE5(( "  left side bearing (font units): %d\n", *lsb ));
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
87aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  /* Return the vertical metrics in font units for a given glyph.          */
88ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease  /* See macro `TT_LOADER_SET_PP' below for explanations.                  */
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
90295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  FT_LOCAL_DEF( void )
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  TT_Get_VMetrics( TT_Face     face,
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_UInt     idx,
93ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease                   FT_Pos      yMax,
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Short*   tsb,
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_UShort*  ah )
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->vertical_info )
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, idx, tsb, ah );
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( face->os2.version != 0xFFFFU )
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1029c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      *tsb = (FT_Short)( face->os2.sTypoAscender - yMax );
103fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      *ah  = (FT_UShort)FT_ABS( face->os2.sTypoAscender -
104fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                face->os2.sTypoDescender );
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
106ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1099c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      *tsb = (FT_Short)( face->horizontal.Ascender - yMax );
110fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      *ah  = (FT_UShort)FT_ABS( face->horizontal.Ascender -
111fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                face->horizontal.Descender );
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
114295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_TRACE5(( "  advance height (font units): %d\n", *ah ));
115295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_TRACE5(( "  top side bearing (font units): %d\n", *tsb ));
116295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  }
117295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
118295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
119ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease  static FT_Error
120295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  tt_get_metrics( TT_Loader  loader,
121295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                  FT_UInt    glyph_index )
122295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  {
123727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    TT_Face    face   = (TT_Face)loader->face;
124727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
125727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
126727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif
127295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
128ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    FT_Error   error;
129ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    FT_Stream  stream = loader->stream;
130ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
131295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_Short   left_bearing = 0, top_bearing = 0;
132295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_UShort  advance_width = 0, advance_height = 0;
133295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
134ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /* we must preserve the stream position          */
135ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /* (which gets altered by the metrics functions) */
136ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    FT_ULong  pos = FT_STREAM_POS();
137ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
138295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
139295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    TT_Get_HMetrics( face, glyph_index,
140295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                     &left_bearing,
141295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                     &advance_width );
142295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    TT_Get_VMetrics( face, glyph_index,
143ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease                     loader->bbox.yMax,
144295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                     &top_bearing,
145295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                     &advance_height );
146295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
147ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    if ( FT_STREAM_SEEK( pos ) )
148ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      return error;
149ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
150aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    loader->left_bearing = left_bearing;
151aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    loader->advance      = advance_width;
152aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    loader->top_bearing  = top_bearing;
153aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    loader->vadvance     = advance_height;
154aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
155727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
156fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
157fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki         loader->exec                                             )
158727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
159fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      loader->exec->sph_tweak_flags = 0;
160727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
161fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      /* This may not be the right place for this, but it works...  */
162fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      /* Note that we have to unconditionally load the tweaks since */
163fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      /* it is possible that glyphs individually switch ClearType's */
164fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      /* backwards compatibility mode on and off.                   */
165fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      sph_set_tweaks( loader, glyph_index );
166727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
167727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
168727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
169aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    if ( !loader->linear_def )
170aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    {
171aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      loader->linear_def = 1;
172aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      loader->linear     = advance_width;
173aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    }
174ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
175ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    return FT_Err_Ok;
176aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  }
177aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
178aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
179295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifdef FT_CONFIG_OPTION_INCREMENTAL
180295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
181aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  static void
182aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  tt_get_metrics_incr_overrides( TT_Loader  loader,
183aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                                 FT_UInt    glyph_index )
184aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  {
185aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    TT_Face  face = (TT_Face)loader->face;
186aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
187aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_Short   left_bearing = 0, top_bearing = 0;
188aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_UShort  advance_width = 0, advance_height = 0;
189aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
190aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
191295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* If this is an incrementally loaded font check whether there are */
192295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* overriding metrics for this glyph.                              */
193295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( face->root.internal->incremental_interface                           &&
194295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner         face->root.internal->incremental_interface->funcs->get_glyph_metrics )
195295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    {
196295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_Incremental_MetricsRec  metrics;
197295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_Error                   error;
198295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
199295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
200aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      metrics.bearing_x = loader->left_bearing;
201295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      metrics.bearing_y = 0;
202aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      metrics.advance   = loader->advance;
203295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      metrics.advance_v = 0;
204295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
205295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
206295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                face->root.internal->incremental_interface->object,
207295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                glyph_index, FALSE, &metrics );
208295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      if ( error )
209295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        goto Exit;
210295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
211295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      left_bearing  = (FT_Short)metrics.bearing_x;
212295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      advance_width = (FT_UShort)metrics.advance;
213295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
214295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#if 0
215295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
216295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      /* GWW: Do I do the same for vertical metrics? */
217295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      metrics.bearing_x = 0;
218aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      metrics.bearing_y = loader->top_bearing;
219aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      metrics.advance   = loader->vadvance;
220295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
221295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
222295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                face->root.internal->incremental_interface->object,
223295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                glyph_index, TRUE, &metrics );
224295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      if ( error )
225295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        goto Exit;
226295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
227295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      top_bearing    = (FT_Short)metrics.bearing_y;
228295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      advance_height = (FT_UShort)metrics.advance;
229295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
230295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif /* 0 */
231295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
232aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      loader->left_bearing = left_bearing;
233aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      loader->advance      = advance_width;
234aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      loader->top_bearing  = top_bearing;
235aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      loader->vadvance     = advance_height;
236aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
237aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( !loader->linear_def )
238aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      {
239aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        loader->linear_def = 1;
240aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        loader->linear     = advance_width;
241aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      }
242295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    }
243295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
244295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  Exit:
245aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    return;
246aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich  }
247295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
248295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif /* FT_CONFIG_OPTION_INCREMENTAL */
249295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Translates an array of coordinates.                                   */
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  translate_array( FT_UInt     n,
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Vector*  coords,
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Pos      delta_x,
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Pos      delta_y )
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  k;
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( delta_x )
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( k = 0; k < n; k++ )
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        coords[k].x += delta_x;
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( delta_y )
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( k = 0; k < n; k++ )
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        coords[k].y += delta_y;
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The following functions are used by default with TrueType fonts.      */
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* However, they can be replaced by alternatives if we need to support   */
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* TrueType-compressed formats (like MicroType) in the future.           */
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_CALLBACK_DEF( FT_Error )
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  TT_Access_Glyph_Frame( TT_Loader  loader,
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_UInt    glyph_index,
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_ULong   offset,
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_UInt    byte_count )
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error   error;
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream  stream = loader->stream;
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* for non-debug mode */
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( glyph_index );
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
295aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    FT_TRACE4(( "Glyph %ld\n", glyph_index ));
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the following line sets the `error' variable through macros! */
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) )
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->cursor = stream->cursor;
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->limit  = stream->limit;
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
304727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_Err_Ok;
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_CALLBACK_DEF( void )
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  TT_Forget_Glyph_Frame( TT_Loader  loader )
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream  stream = loader->stream;
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FRAME_EXIT();
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_CALLBACK_DEF( FT_Error )
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  TT_Load_Glyph_Header( TT_Loader  loader )
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  p     = loader->cursor;
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*  limit = loader->limit;
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( p + 10 > limit )
326727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Outline );
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->n_contours = FT_NEXT_SHORT( p );
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->bbox.xMin = FT_NEXT_SHORT( p );
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->bbox.yMin = FT_NEXT_SHORT( p );
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->bbox.xMax = FT_NEXT_SHORT( p );
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->bbox.yMax = FT_NEXT_SHORT( p );
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE5(( "  # of contours: %d\n", loader->n_contours ));
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE5(( "  xMin: %4d  xMax: %4d\n", loader->bbox.xMin,
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                            loader->bbox.xMax ));
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE5(( "  yMin: %4d  yMax: %4d\n", loader->bbox.yMin,
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                            loader->bbox.yMax ));
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->cursor = p;
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
342727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_Err_Ok;
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_CALLBACK_DEF( FT_Error )
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  TT_Load_Simple_Glyph( TT_Loader  load )
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error        error;
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*        p          = load->cursor;
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*        limit      = load->limit;
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoader  gloader    = load->gloader;
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int          n_contours = load->n_contours;
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Outline*     outline;
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UShort       n_ins;
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int          n_points;
357ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    FT_ULong        tmp;
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte         *flag, *flag_limit;
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte         c, count;
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector       *vec, *vec_limit;
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pos          x;
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Short        *cont, *cont_limit, prev_cont;
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int          xy_size = 0;
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check that we can add the contours to the glyph */
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_GLYPHLOADER_CHECK_POINTS( gloader, 0, n_contours );
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* reading the contours' endpoints & number of points */
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cont       = gloader->current.outline.contours;
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cont_limit = cont + n_contours;
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check space for contours array + instructions count */
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit )
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Invalid_Outline;
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
38041371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    prev_cont = FT_NEXT_SHORT( p );
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( n_contours > 0 )
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cont[0] = prev_cont;
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
38541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    if ( prev_cont < 0 )
38641371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      goto Invalid_Outline;
38741371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( cont++; cont < cont_limit; cont++ )
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
39041371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      cont[0] = FT_NEXT_SHORT( p );
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cont[0] <= prev_cont )
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* unordered contours: this is invalid */
39441371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier        goto Invalid_Outline;
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      prev_cont = cont[0];
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    n_points = 0;
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( n_contours > 0 )
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      n_points = cont[-1] + 1;
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( n_points < 0 )
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Invalid_Outline;
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* note that we will add four phantom points later */
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_GLYPHLOADER_CHECK_POINTS( gloader, n_points + 4, 0 );
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* reading the bytecode instructions */
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    load->glyph->control_len  = 0;
414fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    load->glyph->control_data = NULL;
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( p + 2 > limit )
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Invalid_Outline;
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    n_ins = FT_NEXT_USHORT( p );
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_TRACE5(( "  Instructions size: %u\n", n_ins ));
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
423ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /* check it */
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ( limit - p ) < n_ins )
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
426295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_TRACE0(( "TT_Load_Simple_Glyph: instruction count mismatch\n" ));
427727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Too_Many_Hints );
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Fail;
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( IS_HINTED( load->load_flags ) )
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
435ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      /* we don't trust `maxSizeOfInstructions' in the `maxp' table */
436ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      /* and thus update the bytecode array size by ourselves       */
437ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
438ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      tmp   = load->exec->glyphSize;
439ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      error = Update_Max( load->exec->memory,
440ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease                          &tmp,
441ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease                          sizeof ( FT_Byte ),
442ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease                          (void*)&load->exec->glyphIns,
443ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease                          n_ins );
444ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
445ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      load->exec->glyphSize = (FT_UShort)tmp;
446ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      if ( error )
447ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        return error;
448ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      load->glyph->control_len  = n_ins;
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      load->glyph->control_data = load->exec->glyphIns;
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_USE_BYTECODE_INTERPRETER */
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    p += n_ins;
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
45941371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    outline = &gloader->current.outline;
46041371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* reading the point tags */
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    flag       = (FT_Byte*)outline->tags;
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    flag_limit = flag + n_points;
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ASSERT( flag != NULL );
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( flag < flag_limit )
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( p + 1 > limit )
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Invalid_Outline;
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *flag++ = c = FT_NEXT_BYTE( p );
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( c & 8 )
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( p + 1 > limit )
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Invalid_Outline;
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        count = FT_NEXT_BYTE( p );
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( flag + (FT_Int)count > flag_limit )
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Invalid_Outline;
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( ; count > 0; count-- )
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          *flag++ = c;
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* reading the X coordinates */
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec       = outline->points;
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec_limit = vec + n_points;
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    flag      = (FT_Byte*)outline->tags;
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    x         = 0;
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( p + xy_size > limit )
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Invalid_Outline;
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; vec < vec_limit; vec++, flag++ )
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
4990a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_Pos   y = 0;
5000a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_Byte  f = *flag;
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( f & 2 )
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( p + 1 > limit )
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Invalid_Outline;
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y = (FT_Pos)FT_NEXT_BYTE( p );
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ( f & 16 ) == 0 )
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          y = -y;
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( ( f & 16 ) == 0 )
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( p + 2 > limit )
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Invalid_Outline;
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y = (FT_Pos)FT_NEXT_SHORT( p );
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x     += y;
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vec->x = x;
5220a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      /* the cast is for stupid compilers */
5230a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      *flag  = (FT_Byte)( f & ~( 2 | 16 ) );
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* reading the Y coordinates */
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec       = gloader->current.outline.points;
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec_limit = vec + n_points;
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    flag      = (FT_Byte*)outline->tags;
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    x         = 0;
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; vec < vec_limit; vec++, flag++ )
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
5350a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_Pos   y = 0;
5360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_Byte  f = *flag;
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( f & 4 )
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( p + 1 > limit )
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Invalid_Outline;
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y = (FT_Pos)FT_NEXT_BYTE( p );
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ( f & 32 ) == 0 )
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          y = -y;
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( ( f & 32 ) == 0 )
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( p + 2 > limit )
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Invalid_Outline;
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y = (FT_Pos)FT_NEXT_SHORT( p );
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x     += y;
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vec->y = x;
5580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      /* the cast is for stupid compilers */
5590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      *flag  = (FT_Byte)( f & FT_CURVE_TAG_ON );
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
562fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    outline->n_points   = (FT_Short)n_points;
563fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    outline->n_contours = (FT_Short)n_contours;
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    load->cursor = p;
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Invalid_Outline:
571727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    error = FT_THROW( Invalid_Outline );
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Fail;
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_CALLBACK_DEF( FT_Error )
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  TT_Load_Composite_Glyph( TT_Loader  loader )
578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error        error;
580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*        p       = loader->cursor;
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Byte*        limit   = loader->limit;
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoader  gloader = loader->gloader;
583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_SubGlyph     subglyph;
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt         num_subglyphs;
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    num_subglyphs = 0;
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    do
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Fixed  xx, xy, yy, yx;
592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt   count;
593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* check that we can load a new subglyph */
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs + 1 );
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Fail;
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* check space */
601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( p + 4 > limit )
602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Invalid_Composite;
603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      subglyph = gloader->current.subglyphs + num_subglyphs;
605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      subglyph->arg1 = subglyph->arg2 = 0;
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      subglyph->flags = FT_NEXT_USHORT( p );
609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      subglyph->index = FT_NEXT_USHORT( p );
610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* check space */
612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      count = 2;
613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( subglyph->flags & ARGS_ARE_WORDS )
614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        count += 2;
615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( subglyph->flags & WE_HAVE_A_SCALE )
616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        count += 2;
617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        count += 4;
619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( subglyph->flags & WE_HAVE_A_2X2 )
620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        count += 8;
621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( p + count > limit )
623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Invalid_Composite;
624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* read arguments */
626fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      if ( subglyph->flags & ARGS_ARE_XY_VALUES )
627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
628fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        if ( subglyph->flags & ARGS_ARE_WORDS )
629fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        {
630fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          subglyph->arg1 = FT_NEXT_SHORT( p );
631fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          subglyph->arg2 = FT_NEXT_SHORT( p );
632fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        }
633fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        else
634fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        {
635fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          subglyph->arg1 = FT_NEXT_CHAR( p );
636fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          subglyph->arg2 = FT_NEXT_CHAR( p );
637fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        }
638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
641fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        if ( subglyph->flags & ARGS_ARE_WORDS )
642fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        {
643fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          subglyph->arg1 = (FT_Int)FT_NEXT_USHORT( p );
644fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          subglyph->arg2 = (FT_Int)FT_NEXT_USHORT( p );
645fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        }
646fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        else
647fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        {
648fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          subglyph->arg1 = (FT_Int)FT_NEXT_BYTE( p );
649fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          subglyph->arg2 = (FT_Int)FT_NEXT_BYTE( p );
650fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        }
651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* read transform */
654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      xx = yy = 0x10000L;
655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      xy = yx = 0;
656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( subglyph->flags & WE_HAVE_A_SCALE )
658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;
660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        yy = xx;
661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;
666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( subglyph->flags & WE_HAVE_A_2X2 )
668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;
670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        yx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;
671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        xy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;
672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2;
673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      subglyph->transform.xx = xx;
676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      subglyph->transform.xy = xy;
677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      subglyph->transform.yx = yx;
678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      subglyph->transform.yy = yy;
679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      num_subglyphs++;
681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    } while ( subglyph->flags & MORE_COMPONENTS );
683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    gloader->current.num_subglyphs = num_subglyphs;
685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER
687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream  stream = loader->stream;
690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
6920a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      /* we must undo the FT_FRAME_ENTER in order to point */
6930a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      /* to the composite instructions, if we find some.   */
6940a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      /* We will process them later.                       */
6950a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      /*                                                   */
696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->ins_pos = (FT_ULong)( FT_STREAM_POS() +
697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                    p - limit );
698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->cursor = p;
703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Fail:
705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Invalid_Composite:
708727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    error = FT_THROW( Invalid_Composite );
709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    goto Fail;
710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  TT_Init_Glyph_Loading( TT_Face  face )
715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->access_glyph_frame   = TT_Access_Glyph_Frame;
717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->read_glyph_header    = TT_Load_Glyph_Header;
718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->read_simple_glyph    = TT_Load_Simple_Glyph;
719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->read_composite_glyph = TT_Load_Composite_Glyph;
720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face->forget_glyph_frame   = TT_Forget_Glyph_Frame;
721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_prepare_zone( TT_GlyphZone  zone,
726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_GlyphLoad  load,
727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_UInt       start_point,
728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_UInt       start_contour )
729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
730fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    zone->n_points    = (FT_UShort)load->outline.n_points -
731fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                          (FT_UShort)start_point;
732fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    zone->n_contours  = load->outline.n_contours -
733fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                          (FT_Short)start_contour;
734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    zone->org         = load->extra_points + start_point;
735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    zone->cur         = load->outline.points + start_point;
736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    zone->orus        = load->extra_points2 + start_point;
737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    zone->tags        = (FT_Byte*)load->outline.tags + start_point;
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    zone->contours    = (FT_UShort*)load->outline.contours + start_contour;
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    zone->first_point = (FT_UShort)start_point;
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    TT_Hint_Glyph                                                      */
747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Hint the glyph using the zone prepared by the caller.  Note that   */
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    the zone is supposed to include four phantom points.               */
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  TT_Hint_Glyph( TT_Loader  loader,
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Bool    is_composite )
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
756727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
757727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    TT_Face    face   = (TT_Face)loader->face;
758727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
759727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif
760727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_GlyphZone  zone = &loader->zone;
762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER
764fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    FT_Long       n_ins;
765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( is_composite );
767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER
771295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( loader->glyph->control_len > 0xFFFFL )
772295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    {
773ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      FT_TRACE1(( "TT_Hint_Glyph: too long instructions" ));
774ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      FT_TRACE1(( " (0x%lx byte) is truncated\n",
775295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                 loader->glyph->control_len ));
776295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    }
777fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    n_ins = loader->glyph->control_len;
778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* save original point position in org */
780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( n_ins > 0 )
781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points );
7820a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Reset graphics state. */
784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->exec->GS = ((TT_Size)loader->size)->GS;
785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */
787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      completely refer to the (already) hinted subglyphs.     */
788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( is_composite )
789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->exec->metrics.x_scale = 1 << 16;
791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->exec->metrics.y_scale = 1 << 16;
792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points );
794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->exec->metrics.x_scale =
798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ((TT_Size)loader->size)->metrics.x_scale;
799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->exec->metrics.y_scale =
800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ((TT_Size)loader->size)->metrics.y_scale;
801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
804ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /* round phantom points */
805ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    zone->cur[zone->n_points - 4].x =
806ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      FT_PIX_ROUND( zone->cur[zone->n_points - 4].x );
807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    zone->cur[zone->n_points - 3].x =
808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_PIX_ROUND( zone->cur[zone->n_points - 3].x );
809ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    zone->cur[zone->n_points - 2].y =
810ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      FT_PIX_ROUND( zone->cur[zone->n_points - 2].y );
811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    zone->cur[zone->n_points - 1].y =
812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_PIX_ROUND( zone->cur[zone->n_points - 1].y );
813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER
815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( n_ins > 0 )
817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Error  error;
819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
820295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_GlyphLoader  gloader         = loader->gloader;
821295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_Outline      current_outline = gloader->current.outline;
822295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
824fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      TT_Set_CodeRange( loader->exec, tt_coderange_glyph,
825fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                        loader->exec->glyphIns, n_ins );
826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->exec->is_composite = is_composite;
828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->exec->pts          = *zone;
829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
830fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      error = TT_Run_Context( loader->exec );
831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error && loader->exec->pedantic_hinting )
832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return error;
833295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
834295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      /* store drop-out mode in bits 5-7; set bit 2 also as a marker */
835295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      current_outline.tags[0] |=
836295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE;
837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* save glyph phantom points */
842ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    loader->pp1 = zone->cur[zone->n_points - 4];
843ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    loader->pp2 = zone->cur[zone->n_points - 3];
844ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    loader->pp3 = zone->cur[zone->n_points - 2];
845ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    loader->pp4 = zone->cur[zone->n_points - 1];
846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
847727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
848727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
849727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
850727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN )
851727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_Outline_EmboldenXY( &loader->gloader->current.outline, -24, 0 );
852727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
853727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN )
854727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 );
855727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
856727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
857727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
858727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_Err_Ok;
859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    TT_Process_Simple_Glyph                                            */
866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Once a simple glyph has been loaded, it needs to be processed.     */
869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Usually, this means scaling and hinting through bytecode           */
870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    interpretation.                                                    */
871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  TT_Process_Simple_Glyph( TT_Loader  loader )
874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoader  gloader = loader->gloader;
876727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error        error   = FT_Err_Ok;
877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Outline*     outline;
878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int          n_points;
879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline  = &gloader->current.outline;
882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    n_points = outline->n_points;
883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* set phantom points */
885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline->points[n_points    ] = loader->pp1;
887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline->points[n_points + 1] = loader->pp2;
888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline->points[n_points + 2] = loader->pp3;
889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline->points[n_points + 3] = loader->pp4;
890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline->tags[n_points    ] = 0;
892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline->tags[n_points + 1] = 0;
893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline->tags[n_points + 2] = 0;
894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline->tags[n_points + 3] = 0;
895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    n_points += 4;
897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ((TT_Face)loader->face)->doblend )
901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Deltas apply to the unscaled data. */
903fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      error = TT_Vary_Apply_Glyph_Deltas( (TT_Face)(loader->face),
904fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                           loader->glyph_index,
905fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                           outline,
906fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                           (FT_UInt)n_points );
907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return error;
909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( IS_HINTED( loader->load_flags ) )
914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 );
916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur,
918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     loader->zone.n_points + 4 );
919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
922727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
923727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      TT_Face    face   = (TT_Face)loader->face;
924727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
925727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
926727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_String*  family         = face->root.family_name;
927fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      FT_UInt     ppem           = loader->size->metrics.x_ppem;
928727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_String*  style          = face->root.style_name;
929fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      FT_UInt     x_scale_factor = 1000;
930727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif
931727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
932727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Vector*  vec   = outline->points;
933727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Vector*  limit = outline->points + n_points;
934727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
935727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Fixed  x_scale = 0; /* pacify compiler */
936727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Fixed  y_scale = 0;
937727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
938727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Bool  do_scale = FALSE;
939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
941727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
942727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
943727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
945727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* scale, but only if enabled and only if TT hinting is being used */
946727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( IS_HINTED( loader->load_flags ) )
947727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          x_scale_factor = sph_test_tweak_x_scaling( face,
948727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                                     family,
949727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                                     ppem,
950727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                                     style,
951727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                                     loader->glyph_index );
952727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* scale the glyph */
953727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ||
954727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease             x_scale_factor != 1000                         )
955727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
956727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          x_scale = FT_MulDiv( ((TT_Size)loader->size)->metrics.x_scale,
957fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                               (FT_Long)x_scale_factor, 1000 );
958727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          y_scale = ((TT_Size)loader->size)->metrics.y_scale;
959727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
960727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          /* compensate for any scaling by de/emboldening; */
961727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          /* the amount was determined via experimentation */
962727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          if ( x_scale_factor != 1000 && ppem > 11 )
963727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_Outline_EmboldenXY( outline,
964727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                   FT_MulFix( 1280 * ppem,
965727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                              1000 - x_scale_factor ),
966727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                   0 );
967727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          do_scale = TRUE;
968727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
970727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      else
971727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
972727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
974727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
975727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* scale the glyph */
976727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
977727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
978727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          x_scale = ((TT_Size)loader->size)->metrics.x_scale;
979727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          y_scale = ((TT_Size)loader->size)->metrics.y_scale;
980727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
981727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          do_scale = TRUE;
982727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
983727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
984727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
985727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( do_scale )
986727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
987727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        for ( ; vec < limit; vec++ )
988727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
989727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          vec->x = FT_MulFix( vec->x, x_scale );
990727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          vec->y = FT_MulFix( vec->y, y_scale );
991727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
992727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
993727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        loader->pp1 = outline->points[n_points - 4];
994727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        loader->pp2 = outline->points[n_points - 3];
995727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        loader->pp3 = outline->points[n_points - 2];
996727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        loader->pp4 = outline->points[n_points - 1];
997727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( IS_HINTED( loader->load_flags ) )
1001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->zone.n_points += 4;
1003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = TT_Hint_Glyph( loader, 0 );
1005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
1014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    TT_Process_Composite_Component                                     */
1015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
1017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Once a composite component has been loaded, it needs to be         */
1018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    processed.  Usually, this means transforming and translating.      */
1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  TT_Process_Composite_Component( TT_Loader    loader,
1022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  FT_SubGlyph  subglyph,
1023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  FT_UInt      start_point,
1024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                  FT_UInt      num_base_points )
1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoader  gloader    = loader->gloader;
1027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector*      base_vec   = gloader->base.outline.points;
1028fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    FT_UInt         num_points = (FT_UInt)gloader->base.outline.n_points;
1029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bool         have_scale;
1030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pos          x, y;
1031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    have_scale = FT_BOOL( subglyph->flags & ( WE_HAVE_A_SCALE     |
1034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                              WE_HAVE_AN_XY_SCALE |
1035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                              WE_HAVE_A_2X2       ) );
1036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* perform the transform required for this subglyph */
1038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( have_scale )
1039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt  i;
1041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( i = num_base_points; i < num_points; i++ )
1044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Vector_Transform( base_vec + i, &subglyph->transform );
1045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* get offset */
1048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) )
1049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1050fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      FT_UInt     k = (FT_UInt)subglyph->arg1;
1051fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      FT_UInt     l = (FT_UInt)subglyph->arg2;
1052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Vector*  p1;
1053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Vector*  p2;
1054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* match l-th point of the newly loaded component to the k-th point */
1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* of the previously loaded components.                             */
1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* change to the point numbers used by our outline */
1060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      k += start_point;
1061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      l += num_base_points;
1062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( k >= num_base_points ||
1063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           l >= num_points      )
1064727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        return FT_THROW( Invalid_Composite );
1065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p1 = gloader->base.outline.points + k;
1067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p2 = gloader->base.outline.points + l;
1068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x = p1->x - p2->x;
1070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      y = p1->y - p2->y;
1071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x = subglyph->arg1;
1075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      y = subglyph->arg2;
1076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !x && !y )
1078727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        return FT_Err_Ok;
1079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1080ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      /* Use a default value dependent on                                  */
1081ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED.  This is useful for old */
1082ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      /* TT fonts which don't set the xxx_COMPONENT_OFFSET bit.            */
1083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( have_scale &&
1085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
1086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           !( subglyph->flags & UNSCALED_COMPONENT_OFFSET ) )
1087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
1088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            ( subglyph->flags & SCALED_COMPONENT_OFFSET ) )
1089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
1090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 0
1093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1094ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        /*******************************************************************/
1095ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        /*                                                                 */
1096ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        /* This algorithm is what Apple documents.  But it doesn't work.   */
1097ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        /*                                                                 */
1098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        int  a = subglyph->transform.xx > 0 ?  subglyph->transform.xx
1099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                            : -subglyph->transform.xx;
1100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        int  b = subglyph->transform.yx > 0 ?  subglyph->transform.yx
1101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                            : -subglyph->transform.yx;
1102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        int  c = subglyph->transform.xy > 0 ?  subglyph->transform.xy
1103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                            : -subglyph->transform.xy;
1104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        int  d = subglyph->transform.yy > 0 ? subglyph->transform.yy
1105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                            : -subglyph->transform.yy;
1106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        int  m = a > b ? a : b;
1107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        int  n = c > d ? c : d;
1108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( a - b <= 33 && a - b >= -33 )
1111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          m *= 2;
1112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( c - d <= 33 && c - d >= -33 )
1113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          n *= 2;
1114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        x = FT_MulFix( x, m );
1115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y = FT_MulFix( y, n );
1116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1117ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#else /* 1 */
1118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1119ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        /*******************************************************************/
1120ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        /*                                                                 */
1121ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        /* This algorithm is a guess and works much better than the above. */
1122ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        /*                                                                 */
1123727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_Fixed  mac_xscale = FT_Hypot( subglyph->transform.xx,
1124727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                         subglyph->transform.xy );
1125727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_Fixed  mac_yscale = FT_Hypot( subglyph->transform.yy,
1126727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                         subglyph->transform.yx );
1127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        x = FT_MulFix( x, mac_xscale );
1130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y = FT_MulFix( y, mac_yscale );
1131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1132ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#endif /* 1 */
1133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
1137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Fixed  x_scale = ((TT_Size)loader->size)->metrics.x_scale;
1139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Fixed  y_scale = ((TT_Size)loader->size)->metrics.y_scale;
1140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        x = FT_MulFix( x, x_scale );
1143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y = FT_MulFix( y, y_scale );
1144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( subglyph->flags & ROUND_XY_TO_GRID )
1146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          x = FT_PIX_ROUND( x );
1148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          y = FT_PIX_ROUND( y );
1149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( x || y )
1154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      translate_array( num_points - num_base_points,
1155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       base_vec + num_base_points,
1156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       x, y );
1157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1158727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_Err_Ok;
1159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
1165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    TT_Process_Composite_Glyph                                         */
1166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
1168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    This is slightly different from TT_Process_Simple_Glyph, in that   */
1169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    its sole purpose is to hint the glyph.  Thus this function is      */
1170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    only available when bytecode interpreter is enabled.               */
1171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  TT_Process_Composite_Glyph( TT_Loader  loader,
1174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              FT_UInt    start_point,
1175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              FT_UInt    start_contour )
1176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error     error;
1178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Outline*  outline;
1179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt      i;
1180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline = &loader->gloader->base.outline;
1183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* make room for phantom points */
1185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = FT_GLYPHLOADER_CHECK_POINTS( loader->gloader,
1186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                         outline->n_points + 4,
1187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                         0 );
1188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
1189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
1190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline->points[outline->n_points    ] = loader->pp1;
1192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline->points[outline->n_points + 1] = loader->pp2;
1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline->points[outline->n_points + 2] = loader->pp3;
1194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline->points[outline->n_points + 3] = loader->pp4;
1195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline->tags[outline->n_points    ] = 0;
1197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline->tags[outline->n_points + 1] = 0;
1198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline->tags[outline->n_points + 2] = 0;
1199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    outline->tags[outline->n_points + 3] = 0;
1200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER
1202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream  stream = loader->stream;
1205aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_UShort  n_ins, max_ins;
1206aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      FT_ULong   tmp;
1207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* TT_Load_Composite_Glyph only gives us the offset of instructions */
1210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* so we read them here                                             */
1211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_STREAM_SEEK( loader->ins_pos ) ||
1212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           FT_READ_USHORT( n_ins )           )
1213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return error;
1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_TRACE5(( "  Instructions size = %d\n", n_ins ));
1216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* check it */
1218aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      max_ins = ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions;
1219aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      if ( n_ins > max_ins )
1220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1221ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        /* don't trust `maxSizeOfInstructions'; */
1222ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        /* only do a rough safety check         */
1223aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( (FT_Int)n_ins > loader->byte_len )
1224aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        {
1225ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease          FT_TRACE1(( "TT_Process_Composite_Glyph:"
1226ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease                      " too many instructions (%d) for glyph with length %d\n",
1227aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                      n_ins, loader->byte_len ));
1228727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          return FT_THROW( Too_Many_Hints );
1229aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        }
1230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1231ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        tmp   = loader->exec->glyphSize;
1232aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        error = Update_Max( loader->exec->memory,
1233aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                            &tmp,
1234aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                            sizeof ( FT_Byte ),
1235aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                            (void*)&loader->exec->glyphIns,
1236aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich                            n_ins );
1237ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1238aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        loader->exec->glyphSize = (FT_UShort)tmp;
1239aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( error )
1240aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          return error;
1241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( n_ins == 0 )
1243727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        return FT_Err_Ok;
1244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) )
1246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return error;
1247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->glyph->control_data = loader->exec->glyphIns;
1249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->glyph->control_len  = n_ins;
1250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
1253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    tt_prepare_zone( &loader->zone, &loader->gloader->base,
1255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     start_point, start_contour );
1256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Some points are likely touched during execution of  */
1258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* instructions on components.  So let's untouch them. */
1259ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    for ( i = 0; i < loader->zone.n_points; i++ )
1260295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH;
1261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->zone.n_points += 4;
1263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return TT_Hint_Glyph( loader, 1 );
1265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1268ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease  /*
1269ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * Calculate the phantom points
1270ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1271ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * Defining the right side bearing (rsb) as
1272ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1273ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *   rsb = aw - (lsb + xmax - xmin)
1274ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1275ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * (with `aw' the advance width, `lsb' the left side bearing, and `xmin'
1276ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * and `xmax' the glyph's minimum and maximum x value), the OpenType
1277ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * specification defines the initial position of horizontal phantom points
1278ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * as
1279ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1280ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *   pp1 = (round(xmin - lsb), 0)      ,
1281ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *   pp2 = (round(pp1 + aw), 0)        .
1282ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1283ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * Note that the rounding to the grid (in the device space) is not
1284ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * documented currently in the specification.
1285ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1286ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * However, the specification lacks the precise definition of vertical
1287ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * phantom points.  Greg Hitchcock provided the following explanation.
1288ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1289ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * - a `vmtx' table is present
1290ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1291ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *   For any glyph, the minimum and maximum y values (`ymin' and `ymax')
1292ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *   are given in the `glyf' table, the top side bearing (tsb) and advance
1293ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *   height (ah) are given in the `vmtx' table.  The bottom side bearing
1294ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *   (bsb) is then calculated as
1295ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1296ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *     bsb = ah - (tsb + ymax - ymin)       ,
1297ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1298ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *   and the initial position of vertical phantom points is
1299ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1300ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *     pp3 = (x, round(ymax + tsb))       ,
1301ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *     pp4 = (x, round(pp3 - ah))         .
1302ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1303ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *   See below for value `x'.
1304ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1305ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * - no `vmtx' table in the font
1306ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1307ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *   If there is an `OS/2' table, we set
1308ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1309ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *     DefaultAscender = sTypoAscender       ,
1310ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *     DefaultDescender = sTypoDescender     ,
1311ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1312ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *   otherwise we use data from the `hhea' table:
1313ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1314ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *     DefaultAscender = Ascender         ,
1315ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *     DefaultDescender = Descender       .
1316ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1317ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *   With these two variables we can now set
1318ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1319ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *     ah = DefaultAscender - sDefaultDescender    ,
1320ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *     tsb = DefaultAscender - yMax                ,
1321ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1322ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *   and proceed as if a `vmtx' table was present.
1323ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1324ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * Usually we have
1325ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1326ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *   x = aw / 2      ,                                                (1)
1327ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1328ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * but there is one compatibility case where it can be set to
1329ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1330ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *   x = -DefaultDescender -
1331ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *         ((DefaultAscender - DefaultDescender - aw) / 2)     .      (2)
1332ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1333ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * and another one with
1334ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1335ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *   x = 0     .                                                      (3)
1336ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1337ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * In Windows, the history of those values is quite complicated,
1338ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * depending on the hinting engine (that is, the graphics framework).
1339ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1340ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *   framework        from                 to       formula
1341ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *  ----------------------------------------------------------
1342ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *    GDI       Windows 98               current      (1)
1343ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *              (Windows 2000 for NT)
1344ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *    GDI+      Windows XP               Windows 7    (2)
1345ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *    GDI+      Windows 8                current      (3)
1346ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *    DWrite    Windows 7                current      (3)
1347ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1348ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * For simplicity, FreeType uses (1) for grayscale subpixel hinting and
1349ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   * (3) for everything else.
1350ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   *
1351ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease   */
1352ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1353ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define TT_LOADER_SET_PP( loader )                                          \
1355ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease          do                                                                \
1356ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease          {                                                                 \
1357fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki            FT_Bool  subpixel_hinting_ = loader->exec                       \
1358fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                           ? loader->exec->subpixel_hinting \
1359fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                           : 0;                             \
1360fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki            FT_Bool  grayscale_        = loader->exec                       \
1361fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                           ? loader->exec->grayscale        \
1362fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                           : 0;                             \
1363fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki            FT_Bool  use_aw_2_         = (FT_Bool)( subpixel_hinting_ &&    \
1364fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                                    grayscale_        );    \
1365ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease                                                                            \
1366ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease                                                                            \
1367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \
1368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            (loader)->pp1.y = 0;                                            \
1369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            (loader)->pp2.x = (loader)->pp1.x + (loader)->advance;          \
1370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            (loader)->pp2.y = 0;                                            \
1371ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease                                                                            \
1372ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease            (loader)->pp3.x = use_aw_2_ ? (loader)->advance / 2 : 0;        \
1373ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease            (loader)->pp3.y = (loader)->bbox.yMax + (loader)->top_bearing;  \
1374ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease            (loader)->pp4.x = use_aw_2_ ? (loader)->advance / 2 : 0;        \
1375ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease            (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance;         \
1376ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease          } while ( 0 )
1377ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1378ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#else /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1379ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1380ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#define TT_LOADER_SET_PP( loader )                                          \
1381ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease          do                                                                \
1382ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease          {                                                                 \
1383ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease            (loader)->pp1.x = (loader)->bbox.xMin - (loader)->left_bearing; \
1384ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease            (loader)->pp1.y = 0;                                            \
1385ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease            (loader)->pp2.x = (loader)->pp1.x + (loader)->advance;          \
1386ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease            (loader)->pp2.y = 0;                                            \
1387ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease                                                                            \
1388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            (loader)->pp3.x = 0;                                            \
1389ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease            (loader)->pp3.y = (loader)->bbox.yMax + (loader)->top_bearing;  \
1390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            (loader)->pp4.x = 0;                                            \
1391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            (loader)->pp4.y = (loader)->pp3.y - (loader)->vadvance;         \
1392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          } while ( 0 )
1393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1394ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#endif /* !TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1395ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
1400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    load_truetype_glyph                                                */
1401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
1403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Loads a given truetype glyph.  Handles composites and uses a       */
1404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    TT_Loader object.                                                  */
1405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  load_truetype_glyph( TT_Loader  loader,
1408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       FT_UInt    glyph_index,
1409295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                       FT_UInt    recurse_count,
1410295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                       FT_Bool    header_only )
1411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1412727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error        error        = FT_Err_Ok;
1413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Fixed        x_scale, y_scale;
1414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong        offset;
1415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_Face         face         = (TT_Face)loader->face;
1416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoader  gloader      = loader->gloader;
1417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bool         opened_frame = 0;
1418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_CONFIG_OPTION_INCREMENTAL
1420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_StreamRec    inc_stream;
1421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Data         glyph_data;
1422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bool         glyph_data_loaded = 0;
1423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
1424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* some fonts have an incorrect value of `maxComponentDepth', */
1427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* thus we allow depth 1 to catch the majority of them        */
1428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( recurse_count > 1                                   &&
1429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         recurse_count > face->max_profile.maxComponentDepth )
1430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1431727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Invalid_Composite );
1432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1435fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#ifndef FT_CONFIG_OPTION_INCREMENTAL
1436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check glyph index */
1437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
1438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1439727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Invalid_Glyph_Index );
1440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1442fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#endif
1443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->glyph_index = glyph_index;
1445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x_scale = ((TT_Size)loader->size)->metrics.x_scale;
1449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      y_scale = ((TT_Size)loader->size)->metrics.y_scale;
1450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x_scale = 0x10000L;
1454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      y_scale = 0x10000L;
1455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Set `offset' to the start of the glyph relative to the start of */
1458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the `glyf' table, and `byte_len' to the length of the glyph in  */
1459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* bytes.                                                          */
1460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_CONFIG_OPTION_INCREMENTAL
1462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* If we are loading glyph data via the incremental interface, set */
1464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the loader stream to a memory stream reading the data returned  */
1465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* by the interface.                                               */
1466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->root.internal->incremental_interface )
1467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = face->root.internal->incremental_interface->funcs->get_glyph_data(
1469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                face->root.internal->incremental_interface->object,
1470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                glyph_index, &glyph_data );
1471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph_data_loaded = 1;
1475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      offset            = 0;
1476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->byte_len  = glyph_data.length;
1477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) );
1479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Stream_OpenMemory( &inc_stream,
1480fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                            glyph_data.pointer,
1481fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                            (FT_ULong)glyph_data.length );
1482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->stream = &inc_stream;
1484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* FT_CONFIG_OPTION_INCREMENTAL */
1488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      offset = tt_face_get_location( face, glyph_index,
1490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                     (FT_UInt*)&loader->byte_len );
1491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( loader->byte_len > 0 )
1493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1494295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifdef FT_CONFIG_OPTION_INCREMENTAL
1495295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      /* for the incremental interface, `glyf_offset' is always zero */
1496295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      if ( !loader->glyf_offset                        &&
1497295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner           !face->root.internal->incremental_interface )
1498295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#else
14990a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( !loader->glyf_offset )
1500295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif /* FT_CONFIG_OPTION_INCREMENTAL */
15010a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      {
1502295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" ));
1503727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        error = FT_THROW( Invalid_Table );
15040a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        goto Exit;
15050a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      }
15060a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = face->access_glyph_frame( loader, glyph_index,
1508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                        loader->glyf_offset + offset,
1509fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                        (FT_UInt)loader->byte_len );
1510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      opened_frame = 1;
1514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1515295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      /* read glyph header first */
1516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = face->read_glyph_header( loader );
1517ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      if ( error )
1518ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        goto Exit;
1519ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1520ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      /* the metrics must be computed after loading the glyph header */
1521ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      /* since we need the glyph's `yMax' value in case the vertical */
1522ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      /* metrics must be emulated                                    */
1523ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      error = tt_get_metrics( loader, glyph_index );
1524ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      if ( error )
1525ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        goto Exit;
1526ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1527ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      if ( header_only )
1528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( loader->byte_len == 0 || loader->n_contours == 0 )
1532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->bbox.xMin = 0;
1534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->bbox.xMax = 0;
1535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->bbox.yMin = 0;
1536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->bbox.yMax = 0;
1537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1538ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      error = tt_get_metrics( loader, glyph_index );
1539ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      if ( error )
1540ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        goto Exit;
1541ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1542295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      if ( header_only )
1543295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        goto Exit;
1544295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
1545aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* must initialize points before (possibly) overriding */
1546aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      /* glyph metrics from the incremental interface        */
1547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TT_LOADER_SET_PP( loader );
1548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1549aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_CONFIG_OPTION_INCREMENTAL
1550aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      tt_get_metrics_incr_overrides( loader, glyph_index );
1551aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
1552aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ((TT_Face)(loader->face))->doblend )
1556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1557fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        /* a small outline structure with four elements for */
1558fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        /* communication with `TT_Vary_Apply_Glyph_Deltas'  */
1559fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        FT_Vector   points[4];
1560fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        char        tags[4]     = { 1, 1, 1, 1 };
1561fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        short       contours[4] = { 0, 1, 2, 3 };
1562fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        FT_Outline  outline;
1563fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1564fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1565fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        points[0].x = loader->pp1.x;
1566fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        points[0].y = loader->pp1.y;
1567fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        points[1].x = loader->pp2.x;
1568fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        points[1].y = loader->pp2.y;
1569fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1570fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        points[2].x = loader->pp3.x;
1571fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        points[2].y = loader->pp3.y;
1572fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        points[3].x = loader->pp4.x;
1573fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        points[3].y = loader->pp4.y;
1574fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1575fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        outline.n_points   = 4;
1576fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        outline.n_contours = 4;
1577fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        outline.points     = points;
1578fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        outline.tags       = tags;
1579fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        outline.contours   = contours;
1580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1581fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        /* this must be done before scaling */
1582fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        error = TT_Vary_Apply_Glyph_Deltas( (TT_Face)(loader->face),
1583fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                             glyph_index,
1584fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                             &outline,
1585fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                             outline.n_points );
1586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
1587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
1588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1589fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        loader->pp1.x = points[0].x;
1590fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        loader->pp1.y = points[0].y;
1591fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        loader->pp2.x = points[1].x;
1592fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        loader->pp2.y = points[1].y;
1593ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1594fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        loader->pp3.x = points[2].x;
1595fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        loader->pp3.y = points[2].y;
1596fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        loader->pp4.x = points[3].x;
1597fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        loader->pp4.y = points[3].y;
1598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1600ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
1601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1602ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      /* scale phantom points, if necessary; */
1603ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      /* they get rounded in `TT_Hint_Glyph' */
1604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
1607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
1608ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        /* pp1.y and pp2.y are always zero */
1609ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1610ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale );
1611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
1612ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale );
1613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
1614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1616727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_Err_Ok;
1617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1620ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /* must initialize phantom points before (possibly) overriding */
1621ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /* glyph metrics from the incremental interface                */
1622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_LOADER_SET_PP( loader );
1623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1624aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#ifdef FT_CONFIG_OPTION_INCREMENTAL
1625aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    tt_get_metrics_incr_overrides( loader, glyph_index );
1626aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif
1627aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
1628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /***********************************************************************/
1629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /***********************************************************************/
1630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /***********************************************************************/
1631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if it is a simple glyph, load it */
1633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( loader->n_contours > 0 )
1635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = face->read_simple_glyph( loader );
1637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* all data have been read */
1641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->forget_glyph_frame( loader );
1642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      opened_frame = 0;
1643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = TT_Process_Simple_Glyph( loader );
1645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphLoader_Add( gloader );
1649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /***********************************************************************/
1652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /***********************************************************************/
1653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /***********************************************************************/
1654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* otherwise, load a composite! */
1656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( loader->n_contours == -1 )
1657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt   start_point;
1659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_UInt   start_contour;
1660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ULong  ins_pos;  /* position of composite instructions, if any */
1661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1663fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      start_point   = (FT_UInt)gloader->base.outline.n_points;
1664fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      start_contour = (FT_UInt)gloader->base.outline.n_contours;
1665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* for each subglyph, read composite header */
1667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = face->read_composite_glyph( loader );
1668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* store the offset of instructions */
1672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ins_pos = loader->ins_pos;
1673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* all data we need are read */
1675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->forget_glyph_frame( loader );
1676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      opened_frame = 0;
1677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( face->doblend )
1681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1682fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        FT_UInt      i, limit;
1683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_SubGlyph  subglyph;
1684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1685fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        FT_Outline  outline;
1686fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        FT_Vector*  points   = NULL;
1687fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        char*       tags     = NULL;
1688fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        short*      contours = NULL;
1689fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1690fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        FT_Memory  memory = face->root.memory;
1691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1693fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        limit = gloader->current.num_subglyphs;
1694fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1695fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        /* construct an outline structure for              */
1696fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        /* communication with `TT_Vary_Apply_Glyph_Deltas' */
1697fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        outline.n_points   = gloader->current.num_subglyphs + 4;
1698fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        outline.n_contours = outline.n_points;
1699fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1700fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        if ( FT_NEW_ARRAY( points, outline.n_points )   ||
1701fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki             FT_NEW_ARRAY( tags, outline.n_points )     ||
1702fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki             FT_NEW_ARRAY( contours, outline.n_points ) )
1703fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          goto Exit1;
1704fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1705fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs;
1706fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1707fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        for ( i = 0; i < limit; i++, subglyph++ )
1708fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        {
1709fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          /* applying deltas for anchor points doesn't make sense, */
1710fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          /* but we don't have to specially check this since       */
1711fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          /* unused delta values are zero anyways                  */
1712fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          points[i].x = subglyph->arg1;
1713fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          points[i].y = subglyph->arg2;
1714fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          tags[i]     = 1;
1715fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          contours[i] = i;
1716fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        }
1717fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1718fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        points[i].x = loader->pp1.x;
1719fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        points[i].y = loader->pp1.y;
1720fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        tags[i]     = 1;
1721fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        contours[i] = i;
1722fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1723fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        i++;
1724fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        points[i].x = loader->pp2.x;
1725fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        points[i].y = loader->pp2.y;
1726fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        tags[i]     = 1;
1727fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        contours[i] = i;
1728fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1729fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        i++;
1730fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        points[i].x = loader->pp3.x;
1731fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        points[i].y = loader->pp3.y;
1732fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        tags[i]     = 1;
1733fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        contours[i] = i;
1734fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1735fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        i++;
1736fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        points[i].x = loader->pp4.x;
1737fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        points[i].y = loader->pp4.y;
1738fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        tags[i]     = 1;
1739fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        contours[i] = i;
1740fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1741fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        outline.points   = points;
1742fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        outline.tags     = tags;
1743fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        outline.contours = contours;
1744fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1745fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        /* this call provides additional offsets */
1746fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        /* for each component's translation      */
1747fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        if ( ( error = TT_Vary_Apply_Glyph_Deltas(
1748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         face,
1749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         glyph_index,
1750fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                         &outline,
1751fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                         outline.n_points ) ) != 0 )
1752fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          goto Exit1;
1753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs;
1755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1756fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        for ( i = 0; i < limit; i++, subglyph++ )
1757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1758fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          /* XXX: overflow check for subglyph->{arg1,arg2}.         */
1759fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          /*      Deltas must be within signed 16-bit,              */
1760fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          /*      but the restriction of summed deltas is not clear */
1761fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          subglyph->arg1 = (FT_Int16)points[i].x;
1762fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          subglyph->arg2 = (FT_Int16)points[i].y;
1763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1765fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        loader->pp1.x = points[i + 0].x;
1766fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        loader->pp1.y = points[i + 0].y;
1767fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        loader->pp2.x = points[i + 1].x;
1768fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        loader->pp2.y = points[i + 1].y;
1769ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1770fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        loader->pp3.x = points[i + 2].x;
1771fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        loader->pp3.y = points[i + 2].y;
1772fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        loader->pp4.x = points[i + 3].x;
1773fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        loader->pp4.y = points[i + 3].y;
1774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1775fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      Exit1:
1776fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        FT_FREE( outline.points );
1777fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        FT_FREE( outline.tags );
1778fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        FT_FREE( outline.contours );
1779fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1780fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        if ( error )
1781fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          goto Exit;
1782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
1785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1786ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      /* scale phantom points, if necessary; */
1787ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      /* they get rounded in `TT_Hint_Glyph' */
1788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
1791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
1792ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        /* pp1.y and pp2.y are always zero */
1793ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1794ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale );
1795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
1796ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale );
1797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
1798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */
1801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* `as is' in the glyph slot (the client application will be     */
1802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* responsible for interpreting these data)...                   */
1803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( loader->load_flags & FT_LOAD_NO_RECURSE )
1804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_GlyphLoader_Add( gloader );
1806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        loader->glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
1807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*********************************************************************/
1812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*********************************************************************/
1813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*********************************************************************/
1814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_UInt      n, num_base_points;
1817fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        FT_SubGlyph  subglyph       = NULL;
1818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_UInt      num_points     = start_point;
1820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_UInt      num_subglyphs  = gloader->current.num_subglyphs;
1821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_UInt      num_base_subgs = gloader->base.num_subglyphs;
1822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Stream    old_stream     = loader->stream;
1824aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        FT_Int       old_byte_len   = loader->byte_len;
1825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_GlyphLoader_Add( gloader );
1828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* read each subglyph independently */
1830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( n = 0; n < num_subglyphs; n++ )
1831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Vector  pp[4];
1833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* Each time we call load_truetype_glyph in this loop, the   */
1836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* value of `gloader.base.subglyphs' can change due to table */
1837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* reallocations.  We thus need to recompute the subglyph    */
1838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* pointer on each iteration.                                */
1839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          subglyph = gloader->base.subglyphs + num_base_subgs + n;
1840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          pp[0] = loader->pp1;
1842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          pp[1] = loader->pp2;
1843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          pp[2] = loader->pp3;
1844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          pp[3] = loader->pp4;
1845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1846fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          num_base_points = (FT_UInt)gloader->base.outline.n_points;
1847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1848fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          error = load_truetype_glyph( loader,
1849fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                       (FT_UInt)subglyph->index,
1850fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                       recurse_count + 1,
1851fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                       FALSE );
1852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( error )
1853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
1854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* restore subglyph pointer */
1856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          subglyph = gloader->base.subglyphs + num_base_subgs + n;
1857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1858ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease          /* restore phantom points if necessary */
1859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( !( subglyph->flags & USE_MY_METRICS ) )
1860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            loader->pp1 = pp[0];
1862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            loader->pp2 = pp[1];
1863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            loader->pp3 = pp[2];
1864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            loader->pp4 = pp[3];
1865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1867fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          num_points = (FT_UInt)gloader->base.outline.n_points;
1868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( num_points == num_base_points )
1870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            continue;
1871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* gloader->base.outline consists of three parts:               */
1873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */
1874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /*                                                              */
1875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* (1): exists from the beginning                               */
1876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* (2): components that have been loaded so far                 */
1877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* (3): the newly loaded component                              */
1878fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          error = TT_Process_Composite_Component( loader,
1879fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                                  subglyph,
1880fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                                  start_point,
1881fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                                  num_base_points );
1882fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          if ( error )
1883fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki            goto Exit;
1884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1886aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        loader->stream   = old_stream;
1887aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        loader->byte_len = old_byte_len;
1888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* process the glyph */
1890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        loader->ins_pos = ins_pos;
1891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( IS_HINTED( loader->load_flags ) &&
1892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER
1893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             subglyph->flags & WE_HAVE_INSTR &&
1894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
1895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             num_points > start_point )
1896fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        {
1897fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          error = TT_Process_Composite_Glyph( loader,
1898fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                              start_point,
1899fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                              start_contour );
1900fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          if ( error )
1901fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki            goto Exit;
1902fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        }
1903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* invalid composite count (negative but not -1) */
1908727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Invalid_Outline );
1909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
1910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /***********************************************************************/
1913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /***********************************************************************/
1914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /***********************************************************************/
1915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( opened_frame )
1919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->forget_glyph_frame( loader );
1920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_CONFIG_OPTION_INCREMENTAL
1922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( glyph_data_loaded )
1924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      face->root.internal->incremental_interface->funcs->free_glyph_data(
1925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->root.internal->incremental_interface->object,
1926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        &glyph_data );
1927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
1929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
1935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  compute_glyph_metrics( TT_Loader  loader,
1936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_UInt    glyph_index )
1937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1938727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    TT_Face    face   = (TT_Face)loader->face;
1939727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1940727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
1941727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif
1942727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_BBox       bbox;
1944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Fixed      y_scale;
1945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_GlyphSlot  glyph = loader->glyph;
1946727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    TT_Size       size  = (TT_Size)loader->size;
1947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    y_scale = 0x10000L;
1950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      y_scale = size->root.metrics.y_scale;
1952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE )
1954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Outline_Get_CBox( &glyph->outline, &bbox );
1955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bbox = loader->bbox;
1957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* get the device-independent horizontal advance; it is scaled later */
1959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* by the base layer.                                                */
1960aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    glyph->linearHoriAdvance = loader->linear;
1961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    glyph->metrics.horiBearingX = bbox.xMin;
1963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    glyph->metrics.horiBearingY = bbox.yMax;
1964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    glyph->metrics.horiAdvance  = loader->pp2.x - loader->pp1.x;
1965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1966295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* adjust advance width to the value contained in the hdmx table */
1967295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( !face->postscript.isFixedPitch  &&
1968295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner         IS_HINTED( loader->load_flags ) )
1969295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    {
1970295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_Byte*  widthp;
1971295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
1972295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
1973295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      widthp = tt_face_get_device_metrics( face,
1974295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                           size->root.metrics.x_ppem,
1975295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                           glyph_index );
1976295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
1977727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1978727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1979727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
1980727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
1981727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        FT_Bool  ignore_x_mode;
1982727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1983727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1984727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        ignore_x_mode = FT_BOOL( FT_LOAD_TARGET_MODE( loader->load_flags ) !=
1985727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                                 FT_RENDER_MODE_MONO );
1986727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1987727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( widthp                                                   &&
1988727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease             ( ( ignore_x_mode && loader->exec->compatible_widths ) ||
1989727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                !ignore_x_mode                                      ||
1990727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                SPH_OPTION_BITMAP_WIDTHS                            ) )
1991727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          glyph->metrics.horiAdvance = *widthp << 6;
1992727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
1993727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      else
1994727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1995727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
1996727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1997727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
1998727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( widthp )
1999727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          glyph->metrics.horiAdvance = *widthp << 6;
2000727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
2001295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    }
2002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2003295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* set glyph dimensions */
2004295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    glyph->metrics.width  = bbox.xMax - bbox.xMin;
2005295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    glyph->metrics.height = bbox.yMax - bbox.yMin;
2006295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
2007295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* Now take care of vertical metrics.  In the case where there is */
2008295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* no vertical information within the font (relatively common),   */
2009295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* create some metrics manually                                   */
2010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Pos  top;      /* scaled vertical top side bearing  */
2012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Pos  advance;  /* scaled vertical advance height    */
2013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Get the unscaled top bearing and advance height. */
2016295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      if ( face->vertical_info                   &&
2017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           face->vertical.number_Of_VMetrics > 0 )
2018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax,
2020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   y_scale );
2021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( loader->pp3.y <= loader->pp4.y )
2023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          advance = 0;
2024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
2025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          advance = (FT_UShort)FT_DivFix( loader->pp3.y - loader->pp4.y,
2026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                          y_scale );
2027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
2029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Pos  height;
2031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* XXX Compute top side bearing and advance height in  */
2034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /*     Get_VMetrics instead of here.                   */
2035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* NOTE: The OS/2 values are the only `portable' ones, */
2037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /*       which is why we use them, if there is an OS/2 */
2038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /*       table in the font.  Otherwise, we use the     */
2039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /*       values defined in the horizontal header.      */
2040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        height = (FT_Short)FT_DivFix( bbox.yMax - bbox.yMin,
2042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      y_scale );
2043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( face->os2.version != 0xFFFFU )
2044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          advance = (FT_Pos)( face->os2.sTypoAscender -
2045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              face->os2.sTypoDescender );
2046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
2047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          advance = (FT_Pos)( face->horizontal.Ascender -
2048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              face->horizontal.Descender );
2049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        top = ( advance - height ) / 2;
2051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_CONFIG_OPTION_INCREMENTAL
2054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Incremental_InterfaceRec*  incr;
2056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Incremental_MetricsRec     metrics;
2057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Error                      error;
2058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        incr = face->root.internal->incremental_interface;
2061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* If this is an incrementally loaded font see if there are */
2063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* overriding metrics for this glyph.                       */
2064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( incr && incr->funcs->get_glyph_metrics )
2065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
2066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          metrics.bearing_x = 0;
2067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          metrics.bearing_y = top;
2068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          metrics.advance   = advance;
2069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          error = incr->funcs->get_glyph_metrics( incr->object,
2071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                  glyph_index,
2072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                  TRUE,
2073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                  &metrics );
2074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( error )
2075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            return error;
2076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          top     = metrics.bearing_y;
2078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          advance = metrics.advance;
2079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
2080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* GWW: Do vertical metrics get loaded incrementally too? */
2083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* FT_CONFIG_OPTION_INCREMENTAL */
2085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph->linearVertAdvance = advance;
2087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* scale the metrics */
2089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
2090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2091295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        top     = FT_MulFix( top,     y_scale );
2092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        advance = FT_MulFix( advance, y_scale );
2093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* XXX: for now, we have no better algorithm for the lsb, but it */
2096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*      should work fine.                                        */
2097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /*                                                               */
2098295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      glyph->metrics.vertBearingX = glyph->metrics.horiBearingX -
2099295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                      glyph->metrics.horiAdvance / 2;
2100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph->metrics.vertBearingY = top;
2101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph->metrics.vertAdvance  = advance;
2102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
2105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
2109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
2111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  load_sbit_image( TT_Size       size,
2112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   TT_GlyphSlot  glyph,
2113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_UInt       glyph_index,
2114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Int32      load_flags )
2115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_Face             face;
2117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    SFNT_Service        sfnt;
2118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream           stream;
2119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error            error;
2120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_SBit_MetricsRec  metrics;
2121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face   = (TT_Face)glyph->face;
2124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    sfnt   = (SFNT_Service)face->sfnt;
2125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream = face->root.stream;
2126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    error = sfnt->load_sbit_image( face,
2128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   size->strike_index,
2129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   glyph_index,
2130fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                   (FT_UInt)load_flags,
2131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   stream,
2132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   &glyph->bitmap,
2133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   &metrics );
2134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
2135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph->outline.n_points   = 0;
2137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph->outline.n_contours = 0;
2138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph->metrics.width  = (FT_Pos)metrics.width  << 6;
2140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph->metrics.height = (FT_Pos)metrics.height << 6;
2141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6;
2143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6;
2144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph->metrics.horiAdvance  = (FT_Pos)metrics.horiAdvance  << 6;
2145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6;
2147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6;
2148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph->metrics.vertAdvance  = (FT_Pos)metrics.vertAdvance  << 6;
2149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph->format = FT_GLYPH_FORMAT_BITMAP;
2151295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
2152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
2153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        glyph->bitmap_left = metrics.vertBearingX;
2155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        glyph->bitmap_top  = metrics.vertBearingY;
2156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
2158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        glyph->bitmap_left = metrics.horiBearingX;
2160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        glyph->bitmap_top  = metrics.horiBearingY;
2161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
2168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
2171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  tt_loader_init( TT_Loader     loader,
2172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  TT_Size       size,
2173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  TT_GlyphSlot  glyph,
2174295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                  FT_Int32      load_flags,
2175295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                  FT_Bool       glyf_table_only )
2176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2177fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    FT_Error  error;
2178fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
2179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_Face    face;
2180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Stream  stream;
2181727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef TT_USE_BYTECODE_INTERPRETER
2182aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    FT_Bool    pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
2183727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif
2184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    face   = (TT_Face)glyph->face;
2187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    stream = face->root.stream;
2188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MEM_ZERO( loader, sizeof ( TT_LoaderRec ) );
2190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER
2192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* load execution context */
2194295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( IS_HINTED( load_flags ) && !glyf_table_only )
2195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TT_ExecContext  exec;
2197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Bool         grayscale;
2198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2199727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2200727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
2201727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2202fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      FT_Bool  subpixel_hinting = FALSE;
2203727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2204727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#if 0
2205727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      /* not used yet */
2206727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Bool  compatible_widths;
2207727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Bool  symmetrical_smoothing;
2208727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Bool  bgr;
2209fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      FT_Bool  vertical_lcd;
2210727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Bool  subpixel_positioned;
2211fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      FT_Bool  gray_cleartype;
2212727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif
2213727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2214727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2215727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      FT_Bool  reexecute = FALSE;
2216727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
22189c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      if ( size->bytecode_ready < 0 || size->cvt_ready < 0 )
2219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2220fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        error = tt_size_ready_bytecode( size, pedantic );
2221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
2222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return error;
2223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
22249c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      else if ( size->bytecode_ready )
22259c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod        return size->bytecode_ready;
22269c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      else if ( size->cvt_ready )
22279c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod        return size->cvt_ready;
2228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* query new execution context */
2230fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      exec = size->context;
2231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !exec )
2232727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        return FT_THROW( Could_Not_Find_Context );
2233727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2234727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2235727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2236727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
2237727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
2238fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) !=
2239fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                      FT_RENDER_MODE_MONO               )  &&
2240fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                                    SPH_OPTION_SET_SUBPIXEL                );
2241727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2242fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        if ( subpixel_hinting )
2243ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease          grayscale = FALSE;
2244727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        else if ( SPH_OPTION_SET_GRAYSCALE )
2245727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
2246fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          grayscale        = TRUE;
2247fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          subpixel_hinting = FALSE;
2248727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
2249727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        else
2250ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease          grayscale = FALSE;
2251727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2252727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( FT_IS_TRICKY( glyph->face ) )
2253fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          subpixel_hinting = FALSE;
2254727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2255fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        exec->ignore_x_mode      = subpixel_hinting || grayscale;
2256727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
2257727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 )
2258727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          exec->rasterizer_version = TT_INTERPRETER_VERSION_35;
2259727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2260727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#if 1
2261727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        exec->compatible_widths     = SPH_OPTION_SET_COMPATIBLE_WIDTHS;
2262fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        exec->symmetrical_smoothing = TRUE;
2263727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        exec->bgr                   = FALSE;
2264fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        exec->vertical_lcd          = FALSE;
2265727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        exec->subpixel_positioned   = TRUE;
2266fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        exec->gray_cleartype        = FALSE;
2267727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#else /* 0 */
2268727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        exec->compatible_widths =
2269727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2270727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   TT_LOAD_COMPATIBLE_WIDTHS );
2271727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        exec->symmetrical_smoothing =
2272727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2273727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   TT_LOAD_SYMMETRICAL_SMOOTHING );
2274727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        exec->bgr =
2275727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2276727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   TT_LOAD_BGR );
2277fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        exec->vertical_lcd =
2278fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2279fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                   TT_LOAD_VERTICAL_LCD );
2280727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        exec->subpixel_positioned =
2281727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2282727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                   TT_LOAD_SUBPIXEL_POSITIONED );
2283fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        exec->gray_cleartype =
2284fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2285fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                   TT_LOAD_GRAY_CLEARTYPE );
2286727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* 0 */
2287727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2288727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
2289727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      else
2290727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2291727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2293727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
2294727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2295727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                             FT_RENDER_MODE_MONO );
2296727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
2297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2298fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      error = TT_Load_Context( exec, face, size );
2299fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      if ( error )
2300fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        return error;
2301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2302727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2303727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2304727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
2305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2306727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* a change from mono to subpixel rendering (and vice versa) */
2307727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* requires a re-execution of the CVT program                */
2308fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        if ( subpixel_hinting != exec->subpixel_hinting )
2309727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
2310727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_TRACE4(( "tt_loader_init: subpixel hinting change,"
2311727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                      " re-executing `prep' table\n" ));
2312727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2313fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          exec->subpixel_hinting = subpixel_hinting;
2314fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          reexecute              = TRUE;
2315727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
2316727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2317727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* a change from mono to grayscale rendering (and vice versa) */
2318727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* requires a re-execution of the CVT program                 */
2319ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        if ( grayscale != exec->grayscale )
2320727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
2321727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
2322727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                      " re-executing `prep' table\n" ));
2323727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2324ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease          exec->grayscale = grayscale;
2325ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease          reexecute       = TRUE;
2326727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
2327727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
2328727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      else
2329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2330727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* TT_CONFIG_OPTION_SUBPIXEL_HINTING */
2331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2332727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
2333727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* a change from mono to grayscale rendering (and vice versa) */
2334727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* requires a re-execution of the CVT program                 */
2335727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( grayscale != exec->grayscale )
2336727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
2337fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
2338727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                      " re-executing `prep' table\n" ));
2339727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2340727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          exec->grayscale = grayscale;
2341727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          reexecute       = TRUE;
2342727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
2343727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
2344727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2345727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( reexecute )
2346727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
2347fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        FT_UInt  i;
23487f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
2349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( i = 0; i < size->cvt_size; i++ )
2351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
23529c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod        error = tt_size_run_prep( size, pedantic );
23539c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod        if ( error )
23549c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod          return error;
2355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2357fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      /* check whether the cvt program has disabled hinting */
2358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( exec->GS.instruct_control & 1 )
2359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        load_flags |= FT_LOAD_NO_HINTING;
2360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* load default graphics state -- if needed */
2362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( exec->GS.instruct_control & 2 )
2363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        exec->GS = tt_default_graphics_state;
2364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2365fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
2366fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      /* check whether we have a font hinted for ClearType --           */
2367fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      /* note that this flag can also be modified in a glyph's bytecode */
2368fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      if ( exec->GS.instruct_control & 4 )
2369fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki        exec->ignore_x_mode = 0;
2370fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#endif
2371fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
2372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
2373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->exec = exec;
2374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->instructions = exec->glyphIns;
2375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_USE_BYTECODE_INTERPRETER */
2378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* seek to the beginning of the glyph table -- for Type 42 fonts     */
2380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the table might be accessed from a Postscript stream or something */
2381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* else...                                                           */
2382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_CONFIG_OPTION_INCREMENTAL
2384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->root.internal->incremental_interface )
2386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->glyf_offset = 0;
2387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
2388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
2390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2392fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      error = face->goto_table( face, TTAG_glyf, stream, 0 );
2393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2394727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( FT_ERR_EQ( error, Table_Missing ) )
23950a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        loader->glyf_offset = 0;
23960a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      else if ( error )
2397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2398295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_ERROR(( "tt_loader_init: could not access glyph table\n" ));
2399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return error;
2400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
24010a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      else
24020a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        loader->glyf_offset = FT_STREAM_POS();
2403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* get face's glyph loader */
2406295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( !glyf_table_only )
2407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphLoader  gloader = glyph->internal->loader;
2409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphLoader_Rewind( gloader );
2412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->gloader = gloader;
2413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2415fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    loader->load_flags = (FT_ULong)load_flags;
2416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->face   = (FT_Face)face;
2418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->size   = (FT_Size)size;
2419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->glyph  = (FT_GlyphSlot)glyph;
2420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->stream = stream;
2421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2422727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_Err_Ok;
2423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
2427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
2428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
2429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    TT_Load_Glyph                                                      */
2430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
2431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
2432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    A function used to load a single glyph within a given glyph slot,  */
2433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    for a given size.                                                  */
2434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
2435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
2436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    glyph       :: A handle to a target slot object where the glyph    */
2437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                   will be loaded.                                     */
2438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
2439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    size        :: A handle to the source face size at which the glyph */
2440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                   must be scaled/loaded.                              */
2441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
2442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    glyph_index :: The index of the glyph in the font file.            */
2443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
2444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    load_flags  :: A flag indicating what to load for this glyph.  The */
2445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                   FT_LOAD_XXX constants can be used to control the    */
2446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                   glyph loading process (e.g., whether the outline    */
2447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                   should be scaled, whether to load bitmaps or not,   */
2448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                   whether to hint the outline, etc).                  */
2449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
2450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
2451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FreeType error code.  0 means success.                             */
2452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
2453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
2454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  TT_Load_Glyph( TT_Size       size,
2455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 TT_GlyphSlot  glyph,
2456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_UInt       glyph_index,
2457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Int32      load_flags )
2458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error      error;
2460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TT_LoaderRec  loader;
2461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2463ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index ));
2464ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
2465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
2466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* try to load embedded bitmap if any              */
2468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                 */
2469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* XXX: The convention should be emphasized in     */
2470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      the documents because it can be confusing. */
2471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( size->strike_index != 0xFFFFFFFFUL      &&
2472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
2473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = load_sbit_image( size, glyph, glyph_index, load_flags );
2475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !error )
2476295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      {
2477727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( FT_IS_SCALABLE( glyph->face ) )
2478295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        {
2479295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          /* for the bbox we need the header only */
2480295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
2481295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
2482295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          glyph->linearHoriAdvance = loader.linear;
2483fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          glyph->linearVertAdvance = loader.vadvance;
2484727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2485fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          /* sanity checks: if `xxxAdvance' in the sbit metric */
2486fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          /* structure isn't set, use `linearXXXAdvance'      */
2487727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance )
2488727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            glyph->metrics.horiAdvance =
2489727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              FT_MulFix( glyph->linearHoriAdvance,
2490727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                         size->root.metrics.x_scale );
2491fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          if ( !glyph->metrics.vertAdvance && glyph->linearVertAdvance )
2492fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki            glyph->metrics.vertAdvance =
2493fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki              FT_MulFix( glyph->linearVertAdvance,
2494fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                         size->root.metrics.y_scale );
2495295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        }
2496295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
2497727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        return FT_Err_Ok;
2498295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      }
2499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
2502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */
2504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid )
2505727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Size_Handle );
2506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( load_flags & FT_LOAD_SBITS_ONLY )
2508727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
2509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2510295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    error = tt_loader_init( &loader, size, glyph, load_flags, FALSE );
2511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
2512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return error;
2513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    glyph->format        = FT_GLYPH_FORMAT_OUTLINE;
2515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    glyph->num_subglyphs = 0;
2516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    glyph->outline.flags = 0;
2517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* main loading loop */
2519295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    error = load_truetype_glyph( &loader, glyph_index, 0, FALSE );
2520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
2521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( glyph->format == FT_GLYPH_FORMAT_COMPOSITE )
2523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        glyph->num_subglyphs = loader.gloader->base.num_subglyphs;
2525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        glyph->subglyphs     = loader.gloader->base.subglyphs;
2526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
2528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        glyph->outline        = loader.gloader->base.outline;
2530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        glyph->outline.flags &= ~FT_OUTLINE_SINGLE_PASS;
2531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2532aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        /* Translate array so that (0,0) is the glyph's origin.  Note  */
2533aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        /* that this behaviour is independent on the value of bit 1 of */
2534aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        /* the `flags' field in the `head' table -- at least major     */
2535aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        /* applications like Acroread indicate that.                   */
2536aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        if ( loader.pp1.x )
2537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Outline_Translate( &glyph->outline, -loader.pp1.x, 0 );
2538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
25400a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifdef TT_USE_BYTECODE_INTERPRETER
25410a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
25420a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( IS_HINTED( load_flags ) )
25430a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      {
25440a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        if ( loader.exec->GS.scan_control )
25450a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        {
25460a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          /* convert scan conversion mode to FT_OUTLINE_XXX flags */
25470a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          switch ( loader.exec->GS.scan_type )
25480a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          {
25490a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          case 0: /* simple drop-outs including stubs */
25500a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            glyph->outline.flags |= FT_OUTLINE_INCLUDE_STUBS;
25510a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            break;
25520a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          case 1: /* simple drop-outs excluding stubs */
25530a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            /* nothing; it's the default rendering mode */
25540a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            break;
25550a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          case 4: /* smart drop-outs including stubs */
25560a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS |
25570a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                                    FT_OUTLINE_INCLUDE_STUBS;
25580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            break;
25590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          case 5: /* smart drop-outs excluding stubs  */
25600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS;
25610a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            break;
25620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
25630a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          default: /* no drop-out control */
25640a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS;
25650a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            break;
25660a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          }
25670a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        }
2568295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        else
25690a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS;
25700a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      }
25710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
25720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif /* TT_USE_BYTECODE_INTERPRETER */
25730a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
2574fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      error = compute_glyph_metrics( &loader, glyph_index );
2575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Set the `high precision' bit flag.                           */
2578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* This is _critical_ to get correct output for monochrome      */
2579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* TrueType glyphs at all sizes using the bytecode interpreter. */
2580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                              */
2581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !( load_flags & FT_LOAD_NO_SCALE ) &&
2582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         size->root.metrics.y_ppem < 24     )
2583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
2584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
2590