10a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/***************************************************************************/
20a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/*                                                                         */
30a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/*  ftadvanc.c                                                             */
40a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/*                                                                         */
50a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/*    Quick computation of advance widths (body).                          */
60a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/*                                                                         */
7727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  Copyright 2008, 2009, 2011, 2013 by                                    */
80a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
90a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/*                                                                         */
100a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/*  This file is part of the FreeType project, and may only be used,       */
110a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/*  modified, and distributed under the terms of the FreeType project      */
120a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
130a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/*  this file you indicate that you have read the license and              */
140a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/*  understand and accept it fully.                                        */
150a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/*                                                                         */
160a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/***************************************************************************/
170a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
180a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
20727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include FT_INTERNAL_DEBUG_H
21727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_ADVANCES_H
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_OBJECTS_H
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
250a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Error
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  _ft_face_scale_advances( FT_Face    face,
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_Fixed*  advances,
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           FT_UInt    count,
300a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                           FT_Int32   flags )
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Fixed  scale;
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt   nn;
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
350a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( flags & FT_LOAD_NO_SCALE )
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return FT_Err_Ok;
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( face->size == NULL )
40727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Size_Handle );
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
420a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( flags & FT_LOAD_VERTICAL_LAYOUT )
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      scale = face->size->metrics.y_scale;
440a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    else
450a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      scale = face->size->metrics.x_scale;
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
470a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* this must be the same scaling as to get linear{Hori,Vert}Advance */
480a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* (see `FT_Load_Glyph' implementation in src/base/ftobjs.c)        */
490a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
500a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    for ( nn = 0; nn < count; nn++ )
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      advances[nn] = FT_MulDiv( advances[nn], scale, 64 );
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
530a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    return FT_Err_Ok;
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
570a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project   /* at the moment, we can perform fast advance retrieval only in */
580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project   /* the following cases:                                         */
590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project   /*                                                              */
600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project   /*  - unscaled load                                             */
610a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project   /*  - unhinted load                                             */
620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project   /*  - light-hinted load                                         */
630a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
640a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define LOAD_ADVANCE_FAST_CHECK( flags )                            \
650a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING )    || \
660a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT )
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
690a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* documentation is in ftadvanc.h */
700a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Advance( FT_Face    face,
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_UInt    gindex,
740a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                  FT_Int32   flags,
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Fixed  *padvance )
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face_GetAdvancesFunc  func;
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
790a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
81727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( gindex >= (FT_UInt)face->num_glyphs )
84727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Glyph_Index );
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    func = face->driver->clazz->get_advances;
870a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Error  error;
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
910a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = func( face, gindex, 1, flags, padvance );
930a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( !error )
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return _ft_face_scale_advances( face, padvance, 1, flags );
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
96727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( FT_ERR_NEQ( error, Unimplemented_Feature ) )
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return error;
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Get_Advances( face, gindex, 1, flags, padvance );
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1040a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* documentation is in ftadvanc.h */
1050a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1060a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Get_Advances( FT_Face    face,
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_UInt    start,
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_UInt    count,
1100a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                   FT_Int32   flags,
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Fixed  *padvances )
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Face_GetAdvancesFunc  func;
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt                  num, end, nn;
1150a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_Error                 error = FT_Err_Ok;
1160a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !face )
119727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Face_Handle );
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1210a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    num = (FT_UInt)face->num_glyphs;
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    end = start + count;
1230a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( start >= num || end < start || end > num )
124727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Glyph_Index );
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1260a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( count == 0 )
1270a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      return FT_Err_Ok;
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    func = face->driver->clazz->get_advances;
1300a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = func( face, start, count, flags, padvances );
1330a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( !error )
13441371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier        return _ft_face_scale_advances( face, padvances, count, flags );
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
136727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( FT_ERR_NEQ( error, Unimplemented_Feature ) )
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return error;
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1400a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    error = FT_Err_Ok;
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1420a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( flags & FT_ADVANCE_FLAG_FAST_ONLY )
143727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Unimplemented_Feature );
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
145295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
1460a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    for ( nn = 0; nn < count; nn++ )
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1480a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      error = FT_Load_Glyph( face, start + nn, flags );
1490a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( error )
1500a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        break;
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15241371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      /* scale from 26.6 to 16.16 */
1530a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
15441371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier                      ? face->glyph->advance.y << 10
15541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier                      : face->glyph->advance.x << 10;
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1570a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
15841371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    return error;
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1610a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/* END */
163