Edit

kc3-lang/freetype/src/sfnt/ttbdf.c

Branch :

  • Show log

    Commit

  • Author : Werner Lemberg
    Date : 2020-06-13 21:15:45
    Hash : 16586859
    Message : Remove redundant inclusion of `ft2build.h'. * */*: Remove `#include <ft2build.h>' where possible. * include/freetype/freetype.h: Remove cpp error about missing inclusion of `ft2build.h'.

  • src/sfnt/ttbdf.c
  • /****************************************************************************
     *
     * ttbdf.c
     *
     *   TrueType and OpenType embedded BDF properties (body).
     *
     * Copyright (C) 2005-2020 by
     * David Turner, Robert Wilhelm, and Werner Lemberg.
     *
     * This file is part of the FreeType project, and may only be used,
     * modified, and distributed under the terms of the FreeType project
     * license, LICENSE.TXT.  By continuing to use, modify, or distribute
     * this file you indicate that you have read the license and
     * understand and accept it fully.
     *
     */
    
    
    #include <freetype/internal/ftdebug.h>
    #include <freetype/internal/ftstream.h>
    #include <freetype/tttags.h>
    #include "ttbdf.h"
    
    #include "sferrors.h"
    
    
    #ifdef TT_CONFIG_OPTION_BDF
    
      /**************************************************************************
       *
       * The macro FT_COMPONENT is used in trace mode.  It is an implicit
       * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
       * messages during execution.
       */
    #undef  FT_COMPONENT
    #define FT_COMPONENT  ttbdf
    
    
      FT_LOCAL_DEF( void )
      tt_face_free_bdf_props( TT_Face  face )
      {
        TT_BDF  bdf = &face->bdf;
    
    
        if ( bdf->loaded )
        {
          FT_Stream  stream = FT_FACE( face )->stream;
    
    
          if ( bdf->table )
            FT_FRAME_RELEASE( bdf->table );
    
          bdf->table_end    = NULL;
          bdf->strings      = NULL;
          bdf->strings_size = 0;
        }
      }
    
    
      static FT_Error
      tt_face_load_bdf_props( TT_Face    face,
                              FT_Stream  stream )
      {
        TT_BDF    bdf = &face->bdf;
        FT_ULong  length;
        FT_Error  error;
    
    
        FT_ZERO( bdf );
    
        error = tt_face_goto_table( face, TTAG_BDF, stream, &length );
        if ( error                                  ||
             length < 8                             ||
             FT_FRAME_EXTRACT( length, bdf->table ) )
        {
          error = FT_THROW( Invalid_Table );
          goto Exit;
        }
    
        bdf->table_end = bdf->table + length;
    
        {
          FT_Byte*   p           = bdf->table;
          FT_UInt    version     = FT_NEXT_USHORT( p );
          FT_UInt    num_strikes = FT_NEXT_USHORT( p );
          FT_ULong   strings     = FT_NEXT_ULONG ( p );
          FT_UInt    count;
          FT_Byte*   strike;
    
    
          if ( version != 0x0001                 ||
               strings < 8                       ||
               ( strings - 8 ) / 4 < num_strikes ||
               strings + 1 > length              )
          {
            goto BadTable;
          }
    
          bdf->num_strikes  = num_strikes;
          bdf->strings      = bdf->table + strings;
          bdf->strings_size = length - strings;
    
          count  = bdf->num_strikes;
          p      = bdf->table + 8;
          strike = p + count * 4;
    
    
          for ( ; count > 0; count-- )
          {
            FT_UInt  num_items = FT_PEEK_USHORT( p + 2 );
    
            /*
             * We don't need to check the value sets themselves, since this
             * is done later.
             */
            strike += 10 * num_items;
    
            p += 4;
          }
    
          if ( strike > bdf->strings )
            goto BadTable;
        }
    
        bdf->loaded = 1;
    
      Exit:
        return error;
    
      BadTable:
        FT_FRAME_RELEASE( bdf->table );
        FT_ZERO( bdf );
        error = FT_THROW( Invalid_Table );
        goto Exit;
      }
    
    
      FT_LOCAL_DEF( FT_Error )
      tt_face_find_bdf_prop( TT_Face           face,
                             const char*       property_name,
                             BDF_PropertyRec  *aprop )
      {
        TT_BDF     bdf   = &face->bdf;
        FT_Size    size  = FT_FACE( face )->size;
        FT_Error   error = FT_Err_Ok;
        FT_Byte*   p;
        FT_UInt    count;
        FT_Byte*   strike;
        FT_Offset  property_len;
    
    
        aprop->type = BDF_PROPERTY_TYPE_NONE;
    
        if ( bdf->loaded == 0 )
        {
          error = tt_face_load_bdf_props( face, FT_FACE( face )->stream );
          if ( error )
            goto Exit;
        }
    
        count  = bdf->num_strikes;
        p      = bdf->table + 8;
        strike = p + 4 * count;
    
        error = FT_ERR( Invalid_Argument );
    
        if ( !size || !property_name )
          goto Exit;
    
        property_len = ft_strlen( property_name );
        if ( property_len == 0 )
          goto Exit;
    
        for ( ; count > 0; count-- )
        {
          FT_UInt  _ppem  = FT_NEXT_USHORT( p );
          FT_UInt  _count = FT_NEXT_USHORT( p );
    
    
          if ( _ppem == size->metrics.y_ppem )
          {
            count = _count;
            goto FoundStrike;
          }
    
          strike += 10 * _count;
        }
        goto Exit;
    
      FoundStrike:
        p = strike;
        for ( ; count > 0; count-- )
        {
          FT_UInt  type = FT_PEEK_USHORT( p + 4 );
    
    
          if ( ( type & 0x10 ) != 0 )
          {
            FT_UInt32  name_offset = FT_PEEK_ULONG( p     );
            FT_UInt32  value       = FT_PEEK_ULONG( p + 6 );
    
            /* be a bit paranoid for invalid entries here */
            if ( name_offset < bdf->strings_size                    &&
                 property_len < bdf->strings_size - name_offset     &&
                 ft_strncmp( property_name,
                             (const char*)bdf->strings + name_offset,
                             bdf->strings_size - name_offset ) == 0 )
            {
              switch ( type & 0x0F )
              {
              case 0x00:  /* string */
              case 0x01:  /* atoms */
                /* check that the content is really 0-terminated */
                if ( value < bdf->strings_size &&
                     ft_memchr( bdf->strings + value, 0, bdf->strings_size ) )
                {
                  aprop->type   = BDF_PROPERTY_TYPE_ATOM;
                  aprop->u.atom = (const char*)bdf->strings + value;
                  error         = FT_Err_Ok;
                  goto Exit;
                }
                break;
    
              case 0x02:
                aprop->type      = BDF_PROPERTY_TYPE_INTEGER;
                aprop->u.integer = (FT_Int32)value;
                error            = FT_Err_Ok;
                goto Exit;
    
              case 0x03:
                aprop->type       = BDF_PROPERTY_TYPE_CARDINAL;
                aprop->u.cardinal = value;
                error             = FT_Err_Ok;
                goto Exit;
    
              default:
                ;
              }
            }
          }
          p += 10;
        }
    
      Exit:
        return error;
      }
    
    #else /* !TT_CONFIG_OPTION_BDF */
    
      /* ANSI C doesn't like empty source files */
      typedef int  _tt_bdf_dummy;
    
    #endif /* !TT_CONFIG_OPTION_BDF */
    
    
    /* END */