~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/freetype/src/sfnt/ttbdf.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************/
 
2
/*                                                                         */
 
3
/*  ttbdf.c                                                                */
 
4
/*                                                                         */
 
5
/*    TrueType and OpenType embedded BDF properties (body).                */
 
6
/*                                                                         */
 
7
/*  Copyright 2005, 2006, 2010 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 = SFNT_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 = SFNT_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 = SFNT_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 = SFNT_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         = SFNT_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            = SFNT_Err_Ok;
 
227
            goto Exit;
 
228
 
 
229
          case 0x03:
 
230
            aprop->type       = BDF_PROPERTY_TYPE_CARDINAL;
 
231
            aprop->u.cardinal = value;
 
232
            error             = SFNT_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 */