afloader.c revision 9c745321260bb728ab1cd1c8fd5f075854b2ad49
1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  afloader.c                                                             */
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*    Auto-fitter glyph loading routines (body).                           */
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
79c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod/*  Copyright 2003-2009, 2011-2014 by                                      */
8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  This file is part of the FreeType project, and may only be used,       */
11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  modified, and distributed under the terms of the FreeType project      */
12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  this file you indicate that you have read the license and              */
14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  understand and accept it fully.                                        */
15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
19727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "afglobal.h"
20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "afloader.h"
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "afhints.h"
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "aferrors.h"
23727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include "afmodule.h"
24ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#include "afpic.h"
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
27aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  /* Initialize glyph loader. */
28aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
30727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  af_loader_init( AF_Module  module )
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
32727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    AF_Loader  loader = module->loader;
33727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Memory  memory = module->root.library->memory;
34727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
35727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ZERO( loader );
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    af_glyph_hints_init( &loader->hints, memory );
39aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef FT_DEBUG_AUTOFIT
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    _af_debug_hints = &loader->hints;
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_GlyphLoader_New( memory, &loader->gloader );
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
46aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  /* Reset glyph loader and compute globals if necessary. */
47aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
49727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  af_loader_reset( AF_Module  module,
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Face    face )
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
52727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Error   error  = FT_Err_Ok;
53727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    AF_Loader  loader = module->loader;
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->face    = face;
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->globals = (AF_FaceGlobals)face->autohint.data;
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoader_Rewind( loader->gloader );
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( loader->globals == NULL )
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
63727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = af_face_globals_new( face, &loader->globals, module );
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !error )
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->autohint.data =
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          (FT_Pointer)loader->globals;
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        face->autohint.finalizer =
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          (FT_Generic_Finalizer)af_face_globals_free;
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
77aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  /* Finalize glyph loader. */
78aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
80727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  af_loader_done( AF_Module  module )
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
82727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    AF_Loader  loader = module->loader;
83727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
84727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    af_glyph_hints_done( &loader->hints );
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->face    = NULL;
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->globals = NULL;
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
90aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#ifdef FT_DEBUG_AUTOFIT
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    _af_debug_hints = NULL;
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoader_Done( loader->gloader );
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->gloader = NULL;
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
98aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  /* Load a single glyph component.  This routine calls itself */
99aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  /* recursively, if necessary, and does the main work of      */
100aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  /* `af_loader_load_glyph.'                                   */
101aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  af_loader_load_g( AF_Loader  loader,
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    AF_Scaler  scaler,
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_UInt    glyph_index,
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Int32   load_flags,
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_UInt    depth )
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error          error;
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face           face     = loader->face;
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphLoader    gloader  = loader->gloader;
1129c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    AF_StyleMetrics   metrics  = loader->metrics;
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    AF_GlyphHints     hints    = &loader->hints;
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GlyphSlot      slot     = face->glyph;
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Slot_Internal  internal = slot->internal;
116727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Int32          flags;
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
119727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    flags = load_flags | FT_LOAD_LINEAR_DESIGN;
120727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    error = FT_Load_Glyph( face, glyph_index, flags );
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( error )
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto Exit;
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    loader->transformed = internal->glyph_transformed;
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( loader->transformed )
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Matrix  inverse;
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->trans_matrix = internal->glyph_matrix;
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->trans_delta  = internal->glyph_delta;
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      inverse = loader->trans_matrix;
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Matrix_Invert( &inverse );
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Vector_Transform( &loader->trans_delta, &inverse );
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    switch ( slot->format )
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_GLYPH_FORMAT_OUTLINE:
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* translate the loaded glyph when an internal transform is needed */
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( loader->transformed )
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Outline_Translate( &slot->outline,
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              loader->trans_delta.x,
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              loader->trans_delta.y );
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
147727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      /* copy the outline points in the loader's current                */
148727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      /* extra points which are used to keep original glyph coordinates */
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_GLYPHLOADER_CHECK_POINTS( gloader,
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           slot->outline.n_points + 4,
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           slot->outline.n_contours );
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ARRAY_COPY( gloader->current.outline.points,
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     slot->outline.points,
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     slot->outline.n_points );
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ARRAY_COPY( gloader->current.outline.contours,
160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     slot->outline.contours,
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     slot->outline.n_contours );
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ARRAY_COPY( gloader->current.outline.tags,
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     slot->outline.tags,
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     slot->outline.n_points );
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gloader->current.outline.n_points   = slot->outline.n_points;
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gloader->current.outline.n_contours = slot->outline.n_contours;
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* compute original horizontal phantom points (and ignore */
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* vertical ones)                                         */
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->pp1.x = hints->x_delta;
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->pp1.y = hints->y_delta;
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance,
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 hints->x_scale ) + hints->x_delta;
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      loader->pp2.y = hints->y_delta;
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* be sure to check for spacing glyphs */
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( slot->outline.n_points == 0 )
180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Hint_Metrics;
181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* now load the slot image into the auto-outline and run the */
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* automatic hinting process                                 */
184ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      {
185ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#ifdef FT_CONFIG_OPTION_PIC
1869c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod        AF_FaceGlobals         globals = loader->globals;
187ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#endif
1889c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod        AF_StyleClass          style_class = metrics->style_class;
189ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        AF_WritingSystemClass  writing_system_class =
1909c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod          AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system];
191ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
192ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1939c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod        if ( writing_system_class->style_hints_apply )
1949c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod          writing_system_class->style_hints_apply( hints,
1959c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod                                                   &gloader->current.outline,
1969c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod                                                   metrics );
197ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      }
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
199aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      /* we now need to adjust the metrics according to the change in */
200aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner      /* width/positioning that occurred during the hinting process   */
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( scaler->render_mode != FT_RENDER_MODE_LIGHT )
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Pos        old_rsb, old_lsb, new_lsb;
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Pos        pp1x_uh, pp2x_uh;
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        AF_AxisHints  axis  = &hints->axis[AF_DIMENSION_HORZ];
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        AF_Edge       edge1 = axis->edges;         /* leftmost edge  */
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        AF_Edge       edge2 = edge1 +
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              axis->num_edges - 1; /* rightmost edge */
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( axis->num_edges > 1 && AF_HINTS_DO_ADVANCE( hints ) )
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
213aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          old_rsb = loader->pp2.x - edge2->opos;
214aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          old_lsb = edge1->opos;
215aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          new_lsb = edge1->pos;
216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* remember unhinted values to later account */
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* for rounding errors                       */
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          pp1x_uh = new_lsb    - old_lsb;
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          pp2x_uh = edge2->pos + old_rsb;
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* prefer too much space over too little space */
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* for very small sizes                        */
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( old_lsb < 24 )
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            pp1x_uh -= 8;
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( old_rsb < 24 )
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            pp2x_uh += 8;
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          loader->pp1.x = FT_PIX_ROUND( pp1x_uh );
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          loader->pp2.x = FT_PIX_ROUND( pp2x_uh );
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( loader->pp1.x >= new_lsb && old_lsb > 0 )
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            loader->pp1.x -= 64;
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( loader->pp2.x <= edge2->pos && old_rsb > 0 )
239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            loader->pp2.x += 64;
240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          slot->lsb_delta = loader->pp1.x - pp1x_uh;
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          slot->rsb_delta = loader->pp2.x - pp2x_uh;
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
246aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_Pos  pp1x = loader->pp1.x;
247aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich          FT_Pos  pp2x = loader->pp2.x;
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
249295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          loader->pp1.x = FT_PIX_ROUND( pp1x );
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          loader->pp2.x = FT_PIX_ROUND( pp2x );
252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          slot->lsb_delta = loader->pp1.x - pp1x;
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          slot->rsb_delta = loader->pp2.x - pp2x;
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
259aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        FT_Pos  pp1x = loader->pp1.x;
260aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich        FT_Pos  pp2x = loader->pp2.x;
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
262295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        loader->pp1.x = FT_PIX_ROUND( pp1x + hints->xmin_delta );
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        loader->pp2.x = FT_PIX_ROUND( pp2x + hints->xmax_delta );
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        slot->lsb_delta = loader->pp1.x - pp1x;
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        slot->rsb_delta = loader->pp2.x - pp2x;
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* good, we simply add the glyph to our loader's base */
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphLoader_Add( gloader );
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    case FT_GLYPH_FORMAT_COMPOSITE:
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_UInt      nn, num_subglyphs = slot->num_subglyphs;
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_UInt      num_base_subgs, start_point;
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_SubGlyph  subglyph;
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        start_point = gloader->base.outline.n_points;
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* first of all, copy the subglyph descriptors in the glyph loader */
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs );
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( error )
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Exit;
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_ARRAY_COPY( gloader->current.subglyphs,
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       slot->subglyphs,
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       num_subglyphs );
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gloader->current.num_subglyphs = num_subglyphs;
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        num_base_subgs                 = gloader->base.num_subglyphs;
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
295aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner        /* now read each subglyph independently */
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        for ( nn = 0; nn < num_subglyphs; nn++ )
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Vector  pp1, pp2;
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_Pos     x, y;
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_UInt    num_points, num_new_points, num_base_points;
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* gloader.current.subglyphs can change during glyph loading due */
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* to re-allocation -- we must recompute the current subglyph on */
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* each iteration                                                */
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          subglyph = gloader->base.subglyphs + num_base_subgs + nn;
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          pp1 = loader->pp1;
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          pp2 = loader->pp2;
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          num_base_points = gloader->base.outline.n_points;
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          error = af_loader_load_g( loader, scaler, subglyph->index,
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                    load_flags, depth + 1 );
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( error )
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* recompute subglyph pointer */
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          subglyph = gloader->base.subglyphs + num_base_subgs + nn;
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
3219c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod          if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS ) )
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            loader->pp1 = pp1;
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            loader->pp2 = pp2;
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          num_points     = gloader->base.outline.n_points;
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          num_new_points = num_points - num_base_points;
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
330aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner          /* now perform the transformation required for this subglyph */
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE    |
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   FT_SUBGLYPH_FLAG_XY_SCALE |
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   FT_SUBGLYPH_FLAG_2X2      ) )
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Vector*  cur   = gloader->base.outline.points +
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                num_base_points;
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Vector*  limit = cur + num_new_points;
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            for ( ; cur < limit; cur++ )
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              FT_Vector_Transform( cur, &subglyph->transform );
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* apply offset */
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) )
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Int      k = subglyph->arg1;
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_UInt     l = subglyph->arg2;
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Vector*  p1;
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Vector*  p2;
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( start_point + k >= num_base_points         ||
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                               l >= (FT_UInt)num_new_points )
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
358727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease              error = FT_THROW( Invalid_Composite );
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Exit;
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            l += num_base_points;
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
364727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            /* for now, only use the current point coordinates; */
365727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            /* we eventually may consider another approach      */
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            p1 = gloader->base.outline.points + start_point + k;
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            p2 = gloader->base.outline.points + start_point + l;
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            x = p1->x - p2->x;
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            y = p1->y - p2->y;
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          else
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta;
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta;
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            x = FT_PIX_ROUND( x );
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            y = FT_PIX_ROUND( y );
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Outline  dummy = gloader->base.outline;
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            dummy.points  += num_base_points;
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            dummy.n_points = (short)num_new_points;
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Outline_Translate( &dummy, x, y );
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      break;
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    default:
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* we don't support other formats (yet?) */
396727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Unimplemented_Feature );
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Hint_Metrics:
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( depth == 0 )
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_BBox    bbox;
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Vector  vvector;
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vvector.x = slot->metrics.vertBearingX - slot->metrics.horiBearingX;
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vvector.y = slot->metrics.vertBearingY - slot->metrics.horiBearingY;
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vvector.x = FT_MulFix( vvector.x, metrics->scaler.x_scale );
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vvector.y = FT_MulFix( vvector.y, metrics->scaler.y_scale );
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* transform the hinted outline if needed */
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( loader->transformed )
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix );
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Vector_Transform( &vvector, &loader->trans_matrix );
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 1
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* we must translate our final outline by -pp1.x and compute */
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* the new metrics                                           */
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( loader->pp1.x )
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 );
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Outline_Get_CBox( &gloader->base.outline, &bbox );
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bbox.xMin = FT_PIX_FLOOR( bbox.xMin );
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bbox.yMin = FT_PIX_FLOOR( bbox.yMin );
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bbox.xMax = FT_PIX_CEIL(  bbox.xMax );
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bbox.yMax = FT_PIX_CEIL(  bbox.yMax );
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->metrics.width        = bbox.xMax - bbox.xMin;
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->metrics.height       = bbox.yMax - bbox.yMin;
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->metrics.horiBearingX = bbox.xMin;
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->metrics.horiBearingY = bbox.yMax;
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->metrics.vertBearingX = FT_PIX_FLOOR( bbox.xMin + vvector.x );
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->metrics.vertBearingY = FT_PIX_FLOOR( bbox.yMax + vvector.y );
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* for mono-width fonts (like Andale, Courier, etc.) we need */
439295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      /* to keep the original rounded advance width; ditto for     */
440295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      /* digits if all have the same advance width                 */
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 0
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !FT_IS_FIXED_WIDTH( slot->face ) )
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                               x_scale );
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
44841371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      if ( scaler->render_mode != FT_RENDER_MODE_LIGHT                      &&
44941371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier           ( FT_IS_FIXED_WIDTH( slot->face )                              ||
45041371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier             ( af_face_globals_is_digit( loader->globals, glyph_index ) &&
45141371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier               metrics->digits_have_same_width                          ) ) )
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                               metrics->scaler.x_scale );
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Set delta values to 0.  Otherwise code that uses them is */
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* going to ruin the fixed advance width.                   */
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        slot->lsb_delta = 0;
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        slot->rsb_delta = 0;
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
461295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      else
462295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      {
463295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        /* non-spacing glyphs must stay as-is */
464295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        if ( slot->metrics.horiAdvance )
465295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
466295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      }
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance,
470aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner                                             metrics->scaler.y_scale );
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance );
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance );
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* now copy outline into glyph slot */
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_GlyphLoader_Rewind( internal->loader );
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_GlyphLoader_CopyPoints( internal->loader, gloader );
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
48141371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      /* reassign all outline fields except flags to protect them */
48241371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      slot->outline.n_contours = internal->loader->base.outline.n_contours;
48341371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      slot->outline.n_points   = internal->loader->base.outline.n_points;
48441371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      slot->outline.points     = internal->loader->base.outline.points;
48541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      slot->outline.tags       = internal->loader->base.outline.tags;
48641371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      slot->outline.contours   = internal->loader->base.outline.contours;
48741371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      slot->format  = FT_GLYPH_FORMAT_OUTLINE;
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
496aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner  /* Load a glyph. */
497aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Error )
499727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  af_loader_load_glyph( AF_Module  module,
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Face    face,
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_UInt    gindex,
50241371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier                        FT_Int32   load_flags )
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error      error;
505727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Size       size   = face->size;
506727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    AF_Loader     loader = module->loader;
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    AF_ScalerRec  scaler;
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !size )
511727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ZERO( &scaler );
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    scaler.face    = face;
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    scaler.x_scale = size->metrics.x_scale;
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    scaler.x_delta = 0;  /* XXX: TODO: add support for sub-pixel hinting */
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    scaler.y_scale = size->metrics.y_scale;
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    scaler.y_delta = 0;  /* XXX: TODO: add support for sub-pixel hinting */
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    scaler.flags       = 0;  /* XXX: fix this */
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
524727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    error = af_loader_reset( module, face );
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !error )
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
5279c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      AF_StyleMetrics  metrics;
5289c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      FT_UInt          options = AF_STYLE_NONE_DFLT;
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_OPTION_AUTOFIT2
532ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      /* XXX: undocumented hook to activate the latin2 writing system */
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( load_flags & ( 1UL << 20 ) )
5349c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod        options = AF_STYLE_LTN2_DFLT;
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = af_face_globals_get_metrics( loader->globals, gindex,
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                           options, &metrics );
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !error )
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
541ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#ifdef FT_CONFIG_OPTION_PIC
5429c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod        AF_FaceGlobals         globals = loader->globals;
543ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#endif
5449c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod        AF_StyleClass          style_class = metrics->style_class;
545ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        AF_WritingSystemClass  writing_system_class =
5469c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod          AF_WRITING_SYSTEM_CLASSES_GET[style_class->writing_system];
547ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
548ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        loader->metrics = metrics;
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
5519c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod        if ( writing_system_class->style_metrics_scale )
5529c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod          writing_system_class->style_metrics_scale( metrics, &scaler );
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          metrics->scaler = scaler;
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        load_flags |=  FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM;
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        load_flags &= ~FT_LOAD_RENDER;
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
5599c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod        if ( writing_system_class->style_hints_init )
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
5619c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod          error = writing_system_class->style_hints_init( &loader->hints,
5629c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod                                                          metrics );
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( error )
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Exit;
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 );
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
576