tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ftadvanc.c (4906B)


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