misc/libfreetype/src/base/ftadvanc.c
changeset 5172 88f2e05288ba
equal deleted inserted replaced
5171:f9283dc4860d 5172:88f2e05288ba
       
     1 /***************************************************************************/
       
     2 /*                                                                         */
       
     3 /*  ftadvanc.c                                                             */
       
     4 /*                                                                         */
       
     5 /*    Quick computation of advance widths (body).                          */
       
     6 /*                                                                         */
       
     7 /*  Copyright 2008, 2009 by                                                */
       
     8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
       
     9 /*                                                                         */
       
    10 /*  This file is part of the FreeType project, and may only be used,       */
       
    11 /*  modified, and distributed under the terms of the FreeType project      */
       
    12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
       
    13 /*  this file you indicate that you have read the license and              */
       
    14 /*  understand and accept it fully.                                        */
       
    15 /*                                                                         */
       
    16 /***************************************************************************/
       
    17 
       
    18 
       
    19 #include <ft2build.h>
       
    20 #include FT_ADVANCES_H
       
    21 #include FT_INTERNAL_OBJECTS_H
       
    22 
       
    23 
       
    24   static FT_Error
       
    25   _ft_face_scale_advances( FT_Face    face,
       
    26                            FT_Fixed*  advances,
       
    27                            FT_UInt    count,
       
    28                            FT_Int32   flags )
       
    29   {
       
    30     FT_Fixed  scale;
       
    31     FT_UInt   nn;
       
    32 
       
    33 
       
    34     if ( flags & FT_LOAD_NO_SCALE )
       
    35       return FT_Err_Ok;
       
    36 
       
    37     if ( face->size == NULL )
       
    38       return FT_Err_Invalid_Size_Handle;
       
    39 
       
    40     if ( flags & FT_LOAD_VERTICAL_LAYOUT )
       
    41       scale = face->size->metrics.y_scale;
       
    42     else
       
    43       scale = face->size->metrics.x_scale;
       
    44 
       
    45     /* this must be the same scaling as to get linear{Hori,Vert}Advance */
       
    46     /* (see `FT_Load_Glyph' implementation in src/base/ftobjs.c)        */
       
    47 
       
    48     for ( nn = 0; nn < count; nn++ )
       
    49       advances[nn] = FT_MulDiv( advances[nn], scale, 64 );
       
    50 
       
    51     return FT_Err_Ok;
       
    52   }
       
    53 
       
    54 
       
    55    /* at the moment, we can perform fast advance retrieval only in */
       
    56    /* the following cases:                                         */
       
    57    /*                                                              */
       
    58    /*  - unscaled load                                             */
       
    59    /*  - unhinted load                                             */
       
    60    /*  - light-hinted load                                         */
       
    61 
       
    62 #define LOAD_ADVANCE_FAST_CHECK( flags )                            \
       
    63           ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING )    || \
       
    64             FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT )
       
    65 
       
    66 
       
    67   /* documentation is in ftadvanc.h */
       
    68 
       
    69   FT_EXPORT_DEF( FT_Error )
       
    70   FT_Get_Advance( FT_Face    face,
       
    71                   FT_UInt    gindex,
       
    72                   FT_Int32   flags,
       
    73                   FT_Fixed  *padvance )
       
    74   {
       
    75     FT_Face_GetAdvancesFunc  func;
       
    76 
       
    77 
       
    78     if ( !face )
       
    79       return FT_Err_Invalid_Face_Handle;
       
    80 
       
    81     if ( gindex >= (FT_UInt)face->num_glyphs )
       
    82       return FT_Err_Invalid_Glyph_Index;
       
    83 
       
    84     func = face->driver->clazz->get_advances;
       
    85     if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )
       
    86     {
       
    87       FT_Error  error;
       
    88 
       
    89 
       
    90       error = func( face, gindex, 1, flags, padvance );
       
    91       if ( !error )
       
    92         return _ft_face_scale_advances( face, padvance, 1, flags );
       
    93 
       
    94       if ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) )
       
    95         return error;
       
    96     }
       
    97 
       
    98     return FT_Get_Advances( face, gindex, 1, flags, padvance );
       
    99   }
       
   100 
       
   101 
       
   102   /* documentation is in ftadvanc.h */
       
   103 
       
   104   FT_EXPORT_DEF( FT_Error )
       
   105   FT_Get_Advances( FT_Face    face,
       
   106                    FT_UInt    start,
       
   107                    FT_UInt    count,
       
   108                    FT_Int32   flags,
       
   109                    FT_Fixed  *padvances )
       
   110   {
       
   111     FT_Face_GetAdvancesFunc  func;
       
   112     FT_UInt                  num, end, nn;
       
   113     FT_Error                 error = FT_Err_Ok;
       
   114 
       
   115 
       
   116     if ( !face )
       
   117       return FT_Err_Invalid_Face_Handle;
       
   118 
       
   119     num = (FT_UInt)face->num_glyphs;
       
   120     end = start + count;
       
   121     if ( start >= num || end < start || end > num )
       
   122       return FT_Err_Invalid_Glyph_Index;
       
   123 
       
   124     if ( count == 0 )
       
   125       return FT_Err_Ok;
       
   126 
       
   127     func = face->driver->clazz->get_advances;
       
   128     if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )
       
   129     {
       
   130       error = func( face, start, count, flags, padvances );
       
   131       if ( !error )
       
   132         goto Exit;
       
   133 
       
   134       if ( error != FT_ERROR_BASE( FT_Err_Unimplemented_Feature ) )
       
   135         return error;
       
   136     }
       
   137 
       
   138     error = FT_Err_Ok;
       
   139 
       
   140     if ( flags & FT_ADVANCE_FLAG_FAST_ONLY )
       
   141       return FT_Err_Unimplemented_Feature;
       
   142 
       
   143     flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
       
   144     for ( nn = 0; nn < count; nn++ )
       
   145     {
       
   146       error = FT_Load_Glyph( face, start + nn, flags );
       
   147       if ( error )
       
   148         break;
       
   149 
       
   150       padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
       
   151                       ? face->glyph->advance.y
       
   152                       : face->glyph->advance.x;
       
   153     }
       
   154 
       
   155     if ( error )
       
   156       return error;
       
   157 
       
   158   Exit:
       
   159     return _ft_face_scale_advances( face, padvances, count, flags );
       
   160   }
       
   161 
       
   162 
       
   163 /* END */