Edit

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

Branch :

  • Show log

    Commit

  • Author : Werner Lemberg
    Date : 2010-06-24 10:34:29
    Hash : f765e440
    Message : */*: Use module specific error names where appropriate.

  • src/sfnt/ttbdf.c
  • /***************************************************************************/
    /*                                                                         */
    /*  ttbdf.c                                                                */
    /*                                                                         */
    /*    TrueType and OpenType embedded BDF properties (body).                */
    /*                                                                         */
    /*  Copyright 2005, 2006, 2010 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 <ft2build.h>
    #include FT_INTERNAL_DEBUG_H
    #include FT_INTERNAL_STREAM_H
    #include FT_TRUETYPE_TAGS_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  trace_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 != NULL )
            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 = SFNT_Err_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 = SFNT_Err_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 = SFNT_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 = SFNT_Err_Invalid_Argument;
    
        if ( size == NULL || property_name == NULL )
          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         = SFNT_Err_Ok;
                  goto Exit;
                }
                break;
    
              case 0x02:
                aprop->type      = BDF_PROPERTY_TYPE_INTEGER;
                aprop->u.integer = (FT_Int32)value;
                error            = SFNT_Err_Ok;
                goto Exit;
    
              case 0x03:
                aprop->type       = BDF_PROPERTY_TYPE_CARDINAL;
                aprop->u.cardinal = value;
                error             = SFNT_Err_Ok;
                goto Exit;
    
              default:
                ;
              }
            }
          }
          p += 10;
        }
    
      Exit:
        return error;
      }
    
    #endif /* TT_CONFIG_OPTION_BDF */
    
    
    /* END */