Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
4349 Serge 1
/***************************************************************************/
2
/*                                                                         */
3
/*  ftpatent.c                                                             */
4
/*                                                                         */
5
/*    FreeType API for checking patented TrueType bytecode instructions    */
6
/*    (body).                                                              */
7
/*                                                                         */
8
/*  Copyright 2007, 2008, 2010 by David Turner.                            */
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
#include 
19
#include FT_FREETYPE_H
20
#include FT_TRUETYPE_TAGS_H
21
#include FT_INTERNAL_OBJECTS_H
22
#include FT_INTERNAL_STREAM_H
23
#include FT_SERVICE_SFNT_H
24
#include FT_SERVICE_TRUETYPE_GLYF_H
25
 
26
 
27
  static FT_Bool
28
  _tt_check_patents_in_range( FT_Stream  stream,
29
                              FT_ULong   size )
30
  {
31
    FT_Bool   result = FALSE;
32
    FT_Error  error;
33
    FT_Bytes  p, end;
34
 
35
 
36
    if ( FT_FRAME_ENTER( size ) )
37
      return 0;
38
 
39
    p   = stream->cursor;
40
    end = p + size;
41
 
42
    while ( p < end )
43
    {
44
      switch (p[0])
45
      {
46
      case 0x06:  /* SPvTL // */
47
      case 0x07:  /* SPvTL +  */
48
      case 0x08:  /* SFvTL // */
49
      case 0x09:  /* SFvTL +  */
50
      case 0x0A:  /* SPvFS    */
51
      case 0x0B:  /* SFvFS    */
52
        result = TRUE;
53
        goto Exit;
54
 
55
      case 0x40:
56
        if ( p + 1 >= end )
57
          goto Exit;
58
 
59
        p += p[1] + 2;
60
        break;
61
 
62
      case 0x41:
63
        if ( p + 1 >= end )
64
          goto Exit;
65
 
66
        p += p[1] * 2 + 2;
67
        break;
68
 
69
      case 0x71:  /* DELTAP2 */
70
      case 0x72:  /* DELTAP3 */
71
      case 0x73:  /* DELTAC0 */
72
      case 0x74:  /* DELTAC1 */
73
      case 0x75:  /* DELTAC2 */
74
        result = TRUE;
75
        goto Exit;
76
 
77
      case 0xB0:
78
      case 0xB1:
79
      case 0xB2:
80
      case 0xB3:
81
      case 0xB4:
82
      case 0xB5:
83
      case 0xB6:
84
      case 0xB7:
85
        p += ( p[0] - 0xB0 ) + 2;
86
        break;
87
 
88
      case 0xB8:
89
      case 0xB9:
90
      case 0xBA:
91
      case 0xBB:
92
      case 0xBC:
93
      case 0xBD:
94
      case 0xBE:
95
      case 0xBF:
96
        p += ( p[0] - 0xB8 ) * 2 + 3;
97
        break;
98
 
99
      default:
100
        p += 1;
101
        break;
102
      }
103
    }
104
 
105
  Exit:
106
    FT_UNUSED( error );
107
    FT_FRAME_EXIT();
108
    return result;
109
  }
110
 
111
 
112
  static FT_Bool
113
  _tt_check_patents_in_table( FT_Face   face,
114
                              FT_ULong  tag )
115
  {
116
    FT_Stream              stream = face->stream;
117
    FT_Error               error  = FT_Err_Ok;
118
    FT_Service_SFNT_Table  service;
119
    FT_Bool                result = FALSE;
120
 
121
 
122
    FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
123
 
124
    if ( service )
125
    {
126
      FT_UInt   i = 0;
127
      FT_ULong  tag_i = 0, offset_i = 0, length_i = 0;
128
 
129
 
130
      for ( i = 0; !error && tag_i != tag ; i++ )
131
        error = service->table_info( face, i,
132
                                     &tag_i, &offset_i, &length_i );
133
 
134
      if ( error                      ||
135
           FT_STREAM_SEEK( offset_i ) )
136
        goto Exit;
137
 
138
      result = _tt_check_patents_in_range( stream, length_i );
139
    }
140
 
141
  Exit:
142
    return result;
143
  }
144
 
145
 
146
  static FT_Bool
147
  _tt_face_check_patents( FT_Face  face )
148
  {
149
    FT_Stream  stream = face->stream;
150
    FT_UInt    gindex;
151
    FT_Error   error;
152
    FT_Bool    result;
153
 
154
    FT_Service_TTGlyf  service;
155
 
156
 
157
    result = _tt_check_patents_in_table( face, TTAG_fpgm );
158
    if ( result )
159
      goto Exit;
160
 
161
    result = _tt_check_patents_in_table( face, TTAG_prep );
162
    if ( result )
163
      goto Exit;
164
 
165
    FT_FACE_FIND_SERVICE( face, service, TT_GLYF );
166
    if ( service == NULL )
167
      goto Exit;
168
 
169
    for ( gindex = 0; gindex < (FT_UInt)face->num_glyphs; gindex++ )
170
    {
171
      FT_ULong  offset, num_ins, size;
172
      FT_Int    num_contours;
173
 
174
 
175
      offset = service->get_location( face, gindex, &size );
176
      if ( size == 0 )
177
        continue;
178
 
179
      if ( FT_STREAM_SEEK( offset )      ||
180
           FT_READ_SHORT( num_contours ) )
181
        continue;
182
 
183
      if ( num_contours >= 0 )  /* simple glyph */
184
      {
185
        if ( FT_STREAM_SKIP( 8 + num_contours * 2 ) )
186
          continue;
187
      }
188
      else  /* compound glyph */
189
      {
190
        FT_Bool  has_instr = 0;
191
 
192
 
193
        if ( FT_STREAM_SKIP( 8 ) )
194
          continue;
195
 
196
        /* now read each component */
197
        for (;;)
198
        {
199
          FT_UInt  flags, toskip;
200
 
201
 
202
          if( FT_READ_USHORT( flags ) )
203
            break;
204
 
205
          toskip = 2 + 1 + 1;
206
 
207
          if ( ( flags & ( 1 << 0 ) ) != 0 )       /* ARGS_ARE_WORDS */
208
            toskip += 2;
209
 
210
          if ( ( flags & ( 1 << 3 ) ) != 0 )       /* WE_HAVE_A_SCALE */
211
            toskip += 2;
212
          else if ( ( flags & ( 1 << 6 ) ) != 0 )  /* WE_HAVE_X_Y_SCALE */
213
            toskip += 4;
214
          else if ( ( flags & ( 1 << 7 ) ) != 0 )  /* WE_HAVE_A_2x2 */
215
            toskip += 8;
216
 
217
          if ( ( flags & ( 1 << 8 ) ) != 0 )       /* WE_HAVE_INSTRUCTIONS */
218
            has_instr = 1;
219
 
220
          if ( FT_STREAM_SKIP( toskip ) )
221
            goto NextGlyph;
222
 
223
          if ( ( flags & ( 1 << 5 ) ) == 0 )       /* MORE_COMPONENTS */
224
            break;
225
        }
226
 
227
        if ( !has_instr )
228
          goto NextGlyph;
229
      }
230
 
231
      if ( FT_READ_USHORT( num_ins ) )
232
        continue;
233
 
234
      result = _tt_check_patents_in_range( stream, num_ins );
235
      if ( result )
236
        goto Exit;
237
 
238
    NextGlyph:
239
      ;
240
    }
241
 
242
  Exit:
243
    return result;
244
  }
245
 
246
 
247
  /* documentation is in freetype.h */
248
 
249
  FT_EXPORT_DEF( FT_Bool )
250
  FT_Face_CheckTrueTypePatents( FT_Face  face )
251
  {
252
    FT_Bool  result = FALSE;
253
 
254
 
255
    if ( face && FT_IS_SFNT( face ) )
256
      result = _tt_face_check_patents( face );
257
 
258
    return result;
259
  }
260
 
261
 
262
  /* documentation is in freetype.h */
263
 
264
  FT_EXPORT_DEF( FT_Bool )
265
  FT_Face_SetUnpatentedHinting( FT_Face  face,
266
                                FT_Bool  value )
267
  {
268
    FT_Bool  result = FALSE;
269
 
270
 
271
#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \
272
    !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER )
273
    if ( face && FT_IS_SFNT( face ) )
274
    {
275
      result = !face->internal->ignore_unpatented_hinter;
276
      face->internal->ignore_unpatented_hinter = !value;
277
    }
278
#else
279
    FT_UNUSED( face );
280
    FT_UNUSED( value );
281
#endif
282
 
283
    return result;
284
  }
285
 
286
/* END */