Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  ftadvanc.c                                                             */
  4. /*                                                                         */
  5. /*    Quick computation of advance widths (body).                          */
  6. /*                                                                         */
  7. /*  Copyright 2008, 2009, 2011, 2013 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_INTERNAL_DEBUG_H
  21.  
  22. #include FT_ADVANCES_H
  23. #include FT_INTERNAL_OBJECTS_H
  24.  
  25.  
  26.   static FT_Error
  27.   _ft_face_scale_advances( FT_Face    face,
  28.                            FT_Fixed*  advances,
  29.                            FT_UInt    count,
  30.                            FT_Int32   flags )
  31.   {
  32.     FT_Fixed  scale;
  33.     FT_UInt   nn;
  34.  
  35.  
  36.     if ( flags & FT_LOAD_NO_SCALE )
  37.       return FT_Err_Ok;
  38.  
  39.     if ( face->size == NULL )
  40.       return FT_THROW( Invalid_Size_Handle );
  41.  
  42.     if ( flags & FT_LOAD_VERTICAL_LAYOUT )
  43.       scale = face->size->metrics.y_scale;
  44.     else
  45.       scale = face->size->metrics.x_scale;
  46.  
  47.     /* this must be the same scaling as to get linear{Hori,Vert}Advance */
  48.     /* (see `FT_Load_Glyph' implementation in src/base/ftobjs.c)        */
  49.  
  50.     for ( nn = 0; nn < count; nn++ )
  51.       advances[nn] = FT_MulDiv( advances[nn], scale, 64 );
  52.  
  53.     return FT_Err_Ok;
  54.   }
  55.  
  56.  
  57.    /* at the moment, we can perform fast advance retrieval only in */
  58.    /* the following cases:                                         */
  59.    /*                                                              */
  60.    /*  - unscaled load                                             */
  61.    /*  - unhinted load                                             */
  62.    /*  - light-hinted load                                         */
  63.  
  64. #define LOAD_ADVANCE_FAST_CHECK( flags )                            \
  65.           ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING )    || \
  66.             FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT )
  67.  
  68.  
  69.   /* documentation is in ftadvanc.h */
  70.  
  71.   FT_EXPORT_DEF( FT_Error )
  72.   FT_Get_Advance( FT_Face    face,
  73.                   FT_UInt    gindex,
  74.                   FT_Int32   flags,
  75.                   FT_Fixed  *padvance )
  76.   {
  77.     FT_Face_GetAdvancesFunc  func;
  78.  
  79.  
  80.     if ( !face )
  81.       return FT_THROW( Invalid_Face_Handle );
  82.  
  83.     if ( gindex >= (FT_UInt)face->num_glyphs )
  84.       return FT_THROW( Invalid_Glyph_Index );
  85.  
  86.     func = face->driver->clazz->get_advances;
  87.     if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )
  88.     {
  89.       FT_Error  error;
  90.  
  91.  
  92.       error = func( face, gindex, 1, flags, padvance );
  93.       if ( !error )
  94.         return _ft_face_scale_advances( face, padvance, 1, flags );
  95.  
  96.       if ( FT_ERR_NEQ( error, Unimplemented_Feature ) )
  97.         return error;
  98.     }
  99.  
  100.     return FT_Get_Advances( face, gindex, 1, flags, padvance );
  101.   }
  102.  
  103.  
  104.   /* documentation is in ftadvanc.h */
  105.  
  106.   FT_EXPORT_DEF( FT_Error )
  107.   FT_Get_Advances( FT_Face    face,
  108.                    FT_UInt    start,
  109.                    FT_UInt    count,
  110.                    FT_Int32   flags,
  111.                    FT_Fixed  *padvances )
  112.   {
  113.     FT_Face_GetAdvancesFunc  func;
  114.     FT_UInt                  num, end, nn;
  115.     FT_Error                 error = FT_Err_Ok;
  116.  
  117.  
  118.     if ( !face )
  119.       return FT_THROW( Invalid_Face_Handle );
  120.  
  121.     num = (FT_UInt)face->num_glyphs;
  122.     end = start + count;
  123.     if ( start >= num || end < start || end > num )
  124.       return FT_THROW( Invalid_Glyph_Index );
  125.  
  126.     if ( count == 0 )
  127.       return FT_Err_Ok;
  128.  
  129.     func = face->driver->clazz->get_advances;
  130.     if ( func && LOAD_ADVANCE_FAST_CHECK( flags ) )
  131.     {
  132.       error = func( face, start, count, flags, padvances );
  133.       if ( !error )
  134.         return _ft_face_scale_advances( face, padvances, count, flags );
  135.  
  136.       if ( FT_ERR_NEQ( error, Unimplemented_Feature ) )
  137.         return error;
  138.     }
  139.  
  140.     error = FT_Err_Ok;
  141.  
  142.     if ( flags & FT_ADVANCE_FLAG_FAST_ONLY )
  143.       return FT_THROW( Unimplemented_Feature );
  144.  
  145.     flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
  146.     for ( nn = 0; nn < count; nn++ )
  147.     {
  148.       error = FT_Load_Glyph( face, start + nn, flags );
  149.       if ( error )
  150.         break;
  151.  
  152.       /* scale from 26.6 to 16.16 */
  153.       padvances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
  154.                       ? face->glyph->advance.y << 10
  155.                       : face->glyph->advance.x << 10;
  156.     }
  157.  
  158.     return error;
  159.   }
  160.  
  161.  
  162. /* END */
  163.