Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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