tor-browser

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

ttbdf.c (6237B)


      1 /****************************************************************************
      2 *
      3 * ttbdf.c
      4 *
      5 *   TrueType and OpenType embedded BDF properties (body).
      6 *
      7 * Copyright (C) 2005-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 #include <freetype/internal/ftstream.h>
     21 #include <freetype/tttags.h>
     22 #include "ttbdf.h"
     23 
     24 #include "sferrors.h"
     25 
     26 
     27 #ifdef TT_CONFIG_OPTION_BDF
     28 
     29  /**************************************************************************
     30   *
     31   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
     32   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
     33   * messages during execution.
     34   */
     35 #undef  FT_COMPONENT
     36 #define FT_COMPONENT  ttbdf
     37 
     38 
     39  FT_LOCAL_DEF( void )
     40  tt_face_free_bdf_props( TT_Face  face )
     41  {
     42    TT_BDF  bdf = &face->bdf;
     43 
     44 
     45    if ( bdf->loaded )
     46    {
     47      FT_Stream  stream = FT_FACE( face )->stream;
     48 
     49 
     50      if ( bdf->table )
     51        FT_FRAME_RELEASE( bdf->table );
     52 
     53      bdf->table_end    = NULL;
     54      bdf->strings      = NULL;
     55      bdf->strings_size = 0;
     56    }
     57  }
     58 
     59 
     60  static FT_Error
     61  tt_face_load_bdf_props( TT_Face    face,
     62                          FT_Stream  stream )
     63  {
     64    TT_BDF    bdf = &face->bdf;
     65    FT_ULong  length;
     66    FT_Error  error;
     67 
     68 
     69    FT_ZERO( bdf );
     70 
     71    error = tt_face_goto_table( face, TTAG_BDF, stream, &length );
     72    if ( error                                  ||
     73         length < 8                             ||
     74         FT_FRAME_EXTRACT( length, bdf->table ) )
     75    {
     76      error = FT_THROW( Invalid_Table );
     77      goto Exit;
     78    }
     79 
     80    bdf->table_end = bdf->table + length;
     81 
     82    {
     83      FT_Byte*   p           = bdf->table;
     84      FT_UInt    version     = FT_NEXT_USHORT( p );
     85      FT_UInt    num_strikes = FT_NEXT_USHORT( p );
     86      FT_ULong   strings     = FT_NEXT_ULONG ( p );
     87      FT_UInt    count;
     88      FT_Byte*   strike;
     89 
     90 
     91      if ( version != 0x0001                 ||
     92           strings < 8                       ||
     93           ( strings - 8 ) / 4 < num_strikes ||
     94           strings + 1 > length              )
     95      {
     96        goto BadTable;
     97      }
     98 
     99      bdf->num_strikes  = num_strikes;
    100      bdf->strings      = bdf->table + strings;
    101      bdf->strings_size = length - strings;
    102 
    103      count  = bdf->num_strikes;
    104      p      = bdf->table + 8;
    105      strike = p + count * 4;
    106 
    107 
    108      for ( ; count > 0; count-- )
    109      {
    110        FT_UInt  num_items = FT_PEEK_USHORT( p + 2 );
    111 
    112        /*
    113         * We don't need to check the value sets themselves, since this
    114         * is done later.
    115         */
    116        strike += 10 * num_items;
    117 
    118        p += 4;
    119      }
    120 
    121      if ( strike > bdf->strings )
    122        goto BadTable;
    123    }
    124 
    125    bdf->loaded = 1;
    126 
    127  Exit:
    128    return error;
    129 
    130  BadTable:
    131    FT_FRAME_RELEASE( bdf->table );
    132    FT_ZERO( bdf );
    133    error = FT_THROW( Invalid_Table );
    134    goto Exit;
    135  }
    136 
    137 
    138  FT_LOCAL_DEF( FT_Error )
    139  tt_face_find_bdf_prop( FT_Face           face,          /* TT_Face */
    140                         const char*       property_name,
    141                         BDF_PropertyRec  *aprop )
    142  {
    143    TT_Face    ttface = (TT_Face)face;
    144    TT_BDF     bdf    = &ttface->bdf;
    145    FT_Size    size   = face->size;
    146    FT_Error   error  = FT_Err_Ok;
    147    FT_Byte*   p;
    148    FT_UInt    count;
    149    FT_Byte*   strike;
    150    FT_Offset  property_len;
    151 
    152 
    153    aprop->type = BDF_PROPERTY_TYPE_NONE;
    154 
    155    if ( bdf->loaded == 0 )
    156    {
    157      error = tt_face_load_bdf_props( ttface, FT_FACE_STREAM( face ) );
    158      if ( error )
    159        goto Exit;
    160    }
    161 
    162    count  = bdf->num_strikes;
    163    p      = bdf->table + 8;
    164    strike = p + 4 * count;
    165 
    166    error = FT_ERR( Invalid_Argument );
    167 
    168    if ( !size || !property_name )
    169      goto Exit;
    170 
    171    property_len = ft_strlen( property_name );
    172    if ( property_len == 0 )
    173      goto Exit;
    174 
    175    for ( ; count > 0; count-- )
    176    {
    177      FT_UInt  _ppem  = FT_NEXT_USHORT( p );
    178      FT_UInt  _count = FT_NEXT_USHORT( p );
    179 
    180 
    181      if ( _ppem == size->metrics.y_ppem )
    182      {
    183        count = _count;
    184        goto FoundStrike;
    185      }
    186 
    187      strike += 10 * _count;
    188    }
    189    goto Exit;
    190 
    191  FoundStrike:
    192    p = strike;
    193    for ( ; count > 0; count-- )
    194    {
    195      FT_UInt  type = FT_PEEK_USHORT( p + 4 );
    196 
    197 
    198      if ( ( type & 0x10 ) != 0 )
    199      {
    200        FT_UInt32  name_offset = FT_PEEK_ULONG( p     );
    201        FT_UInt32  value       = FT_PEEK_ULONG( p + 6 );
    202 
    203        /* be a bit paranoid for invalid entries here */
    204        if ( name_offset < bdf->strings_size                    &&
    205             property_len < bdf->strings_size - name_offset     &&
    206             ft_strncmp( property_name,
    207                         (const char*)bdf->strings + name_offset,
    208                         bdf->strings_size - name_offset ) == 0 )
    209        {
    210          switch ( type & 0x0F )
    211          {
    212          case 0x00:  /* string */
    213          case 0x01:  /* atoms */
    214            /* check that the content is really 0-terminated */
    215            if ( value < bdf->strings_size &&
    216                 ft_memchr( bdf->strings + value, 0, bdf->strings_size ) )
    217            {
    218              aprop->type   = BDF_PROPERTY_TYPE_ATOM;
    219              aprop->u.atom = (const char*)bdf->strings + value;
    220              error         = FT_Err_Ok;
    221              goto Exit;
    222            }
    223            break;
    224 
    225          case 0x02:
    226            aprop->type      = BDF_PROPERTY_TYPE_INTEGER;
    227            aprop->u.integer = (FT_Int32)value;
    228            error            = FT_Err_Ok;
    229            goto Exit;
    230 
    231          case 0x03:
    232            aprop->type       = BDF_PROPERTY_TYPE_CARDINAL;
    233            aprop->u.cardinal = value;
    234            error             = FT_Err_Ok;
    235            goto Exit;
    236 
    237          default:
    238            ;
    239          }
    240        }
    241      }
    242      p += 10;
    243    }
    244 
    245  Exit:
    246    return error;
    247  }
    248 
    249 #else /* !TT_CONFIG_OPTION_BDF */
    250 
    251  /* ANSI C doesn't like empty source files */
    252  typedef int  tt_bdf_dummy_;
    253 
    254 #endif /* !TT_CONFIG_OPTION_BDF */
    255 
    256 
    257 /* END */