PageRenderTime 345ms CodeModel.GetById 171ms app.highlight 17ms RepoModel.GetById 154ms app.codeStats 0ms

/src/compiler/android-ndk/jni/freetype/src/sfnt/ttbdf.c

http://ftk.googlecode.com/
C | 250 lines | 167 code | 54 blank | 29 comment | 27 complexity | a108e29367426406e89a30ad260d5c9e MD5 | raw file
  1/***************************************************************************/
  2/*                                                                         */
  3/*  ttbdf.c                                                                */
  4/*                                                                         */
  5/*    TrueType and OpenType embedded BDF properties (body).                */
  6/*                                                                         */
  7/*  Copyright 2005, 2006 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_Err_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_Err_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 = 0;
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         = 0;
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            = 0;
227            goto Exit;
228
229          case 0x03:
230            aprop->type       = BDF_PROPERTY_TYPE_CARDINAL;
231            aprop->u.cardinal = value;
232            error             = 0;
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 */