ttbdf.c

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  ttbdf.c                                                                */
00004 /*                                                                         */
00005 /*    TrueType and OpenType embedded BDF properties (body).                */
00006 /*                                                                         */
00007 /*  Copyright 2005, 2006 by                                                */
00008 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00009 /*                                                                         */
00010 /*  This file is part of the FreeType project, and may only be used,       */
00011 /*  modified, and distributed under the terms of the FreeType project      */
00012 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00013 /*  this file you indicate that you have read the license and              */
00014 /*  understand and accept it fully.                                        */
00015 /*                                                                         */
00016 /***************************************************************************/
00017 
00018 
00019 #include <ft2build.h>
00020 #include FT_INTERNAL_DEBUG_H
00021 #include FT_INTERNAL_STREAM_H
00022 #include FT_TRUETYPE_TAGS_H
00023 #include "ttbdf.h"
00024 
00025 #include "sferrors.h"
00026 
00027 
00028 #ifdef TT_CONFIG_OPTION_BDF
00029 
00030   /*************************************************************************/
00031   /*                                                                       */
00032   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00033   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00034   /* messages during execution.                                            */
00035   /*                                                                       */
00036 #undef  FT_COMPONENT
00037 #define FT_COMPONENT  trace_ttbdf
00038 
00039 
00040   FT_LOCAL_DEF( void )
00041   tt_face_free_bdf_props( TT_Face  face )
00042   {
00043     TT_BDF  bdf = &face->bdf;
00044 
00045 
00046     if ( bdf->loaded )
00047     {
00048       FT_Stream  stream = FT_FACE(face)->stream;
00049 
00050 
00051       if ( bdf->table != NULL )
00052         FT_FRAME_RELEASE( bdf->table );
00053 
00054       bdf->table_end    = NULL;
00055       bdf->strings      = NULL;
00056       bdf->strings_size = 0;
00057     }
00058   }
00059 
00060 
00061   static FT_Error
00062   tt_face_load_bdf_props( TT_Face    face,
00063                           FT_Stream  stream )
00064   {
00065     TT_BDF    bdf = &face->bdf;
00066     FT_ULong  length;
00067     FT_Error  error;
00068 
00069 
00070     FT_ZERO( bdf );
00071 
00072     error = tt_face_goto_table( face, TTAG_BDF, stream, &length );
00073     if ( error                                  ||
00074          length < 8                             ||
00075          FT_FRAME_EXTRACT( length, bdf->table ) )
00076     {
00077       error = FT_Err_Invalid_Table;
00078       goto Exit;
00079     }
00080 
00081     bdf->table_end = bdf->table + length;
00082 
00083     {
00084       FT_Byte*   p           = bdf->table;
00085       FT_UInt    version     = FT_NEXT_USHORT( p );
00086       FT_UInt    num_strikes = FT_NEXT_USHORT( p );
00087       FT_ULong   strings     = FT_NEXT_ULONG ( p );
00088       FT_UInt    count;
00089       FT_Byte*   strike;
00090 
00091 
00092       if ( version != 0x0001                 ||
00093            strings < 8                       ||
00094            ( strings - 8 ) / 4 < num_strikes ||
00095            strings + 1 > length              )
00096       {
00097         goto BadTable;
00098       }
00099 
00100       bdf->num_strikes  = num_strikes;
00101       bdf->strings      = bdf->table + strings;
00102       bdf->strings_size = length - strings;
00103 
00104       count  = bdf->num_strikes;
00105       p      = bdf->table + 8;
00106       strike = p + count * 4;
00107 
00108 
00109       for ( ; count > 0; count-- )
00110       {
00111         FT_UInt  num_items = FT_PEEK_USHORT( p + 2 );
00112 
00113         /*
00114          *  We don't need to check the value sets themselves, since this
00115          *  is done later.
00116          */
00117         strike += 10 * num_items;
00118 
00119         p += 4;
00120       }
00121 
00122       if ( strike > bdf->strings )
00123         goto BadTable;
00124     }
00125 
00126     bdf->loaded = 1;
00127 
00128   Exit:
00129     return error;
00130 
00131   BadTable:
00132     FT_FRAME_RELEASE( bdf->table );
00133     FT_ZERO( bdf );
00134     error = FT_Err_Invalid_Table;
00135     goto Exit;
00136   }
00137 
00138 
00139   FT_LOCAL_DEF( FT_Error )
00140   tt_face_find_bdf_prop( TT_Face           face,
00141                          const char*       property_name,
00142                          BDF_PropertyRec  *aprop )
00143   {
00144     TT_BDF     bdf   = &face->bdf;
00145     FT_Size    size  = FT_FACE(face)->size;
00146     FT_Error   error = 0;
00147     FT_Byte*   p;
00148     FT_UInt    count;
00149     FT_Byte*   strike;
00150     FT_Offset  property_len;
00151 
00152 
00153     aprop->type = BDF_PROPERTY_TYPE_NONE;
00154 
00155     if ( bdf->loaded == 0 )
00156     {
00157       error = tt_face_load_bdf_props( face, FT_FACE( face )->stream );
00158       if ( error )
00159         goto Exit;
00160     }
00161 
00162     count  = bdf->num_strikes;
00163     p      = bdf->table + 8;
00164     strike = p + 4 * count;
00165 
00166     error = FT_Err_Invalid_Argument;
00167 
00168     if ( size == NULL || property_name == NULL )
00169       goto Exit;
00170 
00171     property_len = ft_strlen( property_name );
00172     if ( property_len == 0 )
00173       goto Exit;
00174 
00175     for ( ; count > 0; count-- )
00176     {
00177       FT_UInt  _ppem  = FT_NEXT_USHORT( p );
00178       FT_UInt  _count = FT_NEXT_USHORT( p );
00179 
00180       if ( _ppem == size->metrics.y_ppem )
00181       {
00182         count = _count;
00183         goto FoundStrike;
00184       }
00185 
00186       strike += 10 * _count;
00187     }
00188     goto Exit;
00189 
00190   FoundStrike:
00191     p = strike;
00192     for ( ; count > 0; count-- )
00193     {
00194       FT_UInt  type = FT_PEEK_USHORT( p + 4 );
00195 
00196       if ( ( type & 0x10 ) != 0 )
00197       {
00198         FT_UInt32  name_offset = FT_PEEK_ULONG( p     );
00199         FT_UInt32  value       = FT_PEEK_ULONG( p + 6 );
00200 
00201         /* be a bit paranoid for invalid entries here */
00202         if ( name_offset < bdf->strings_size                    &&
00203              property_len < bdf->strings_size - name_offset     &&
00204              ft_strncmp( property_name,
00205                          (const char*)bdf->strings + name_offset,
00206                          bdf->strings_size - name_offset ) == 0 )
00207         {
00208           switch ( type & 0x0F )
00209           {
00210           case 0x00:  /* string */
00211           case 0x01:  /* atoms */
00212             /* check that the content is really 0-terminated */
00213             if ( value < bdf->strings_size &&
00214                  ft_memchr( bdf->strings + value, 0, bdf->strings_size ) )
00215             {
00216               aprop->type   = BDF_PROPERTY_TYPE_ATOM;
00217               aprop->u.atom = (const char*)bdf->strings + value;
00218               error         = 0;
00219               goto Exit;
00220             }
00221             break;
00222 
00223           case 0x02:
00224             aprop->type      = BDF_PROPERTY_TYPE_INTEGER;
00225             aprop->u.integer = (FT_Int32)value;
00226             error            = 0;
00227             goto Exit;
00228 
00229           case 0x03:
00230             aprop->type       = BDF_PROPERTY_TYPE_CARDINAL;
00231             aprop->u.cardinal = value;
00232             error             = 0;
00233             goto Exit;
00234 
00235           default:
00236             ;
00237           }
00238         }
00239       }
00240       p += 10;
00241     }
00242 
00243   Exit:
00244     return error;
00245   }
00246 
00247 #endif /* TT_CONFIG_OPTION_BDF */
00248 
00249 
00250 /* END */

Generated on Tue Jul 5 14:13:51 2011 for ROOT_528-00b_version by  doxygen 1.5.1