00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <ft2build.h>
00019 #include FT_FREETYPE_H
00020 #include FT_TRUETYPE_TAGS_H
00021 #include FT_INTERNAL_OBJECTS_H
00022 #include FT_INTERNAL_STREAM_H
00023 #include FT_SERVICE_SFNT_H
00024 #include FT_SERVICE_TRUETYPE_GLYF_H
00025
00026
00027 static FT_Bool
00028 _tt_check_patents_in_range( FT_Stream stream,
00029 FT_ULong size )
00030 {
00031 FT_Bool result = FALSE;
00032 FT_Error error;
00033 FT_Bytes p, end;
00034
00035
00036 if ( FT_FRAME_ENTER( size ) )
00037 return 0;
00038
00039 p = stream->cursor;
00040 end = p + size;
00041
00042 while ( p < end )
00043 {
00044 switch (p[0])
00045 {
00046 case 0x06:
00047 case 0x07:
00048 case 0x08:
00049 case 0x09:
00050 case 0x0A:
00051 case 0x0B:
00052 result = TRUE;
00053 goto Exit;
00054
00055 case 0x40:
00056 if ( p + 1 >= end )
00057 goto Exit;
00058
00059 p += p[1] + 2;
00060 break;
00061
00062 case 0x41:
00063 if ( p + 1 >= end )
00064 goto Exit;
00065
00066 p += p[1] * 2 + 2;
00067 break;
00068
00069 case 0x71:
00070 case 0x72:
00071 case 0x73:
00072 case 0x74:
00073 case 0x75:
00074 result = TRUE;
00075 goto Exit;
00076
00077 case 0xB0:
00078 case 0xB1:
00079 case 0xB2:
00080 case 0xB3:
00081 case 0xB4:
00082 case 0xB5:
00083 case 0xB6:
00084 case 0xB7:
00085 p += ( p[0] - 0xB0 ) + 2;
00086 break;
00087
00088 case 0xB8:
00089 case 0xB9:
00090 case 0xBA:
00091 case 0xBB:
00092 case 0xBC:
00093 case 0xBD:
00094 case 0xBE:
00095 case 0xBF:
00096 p += ( p[0] - 0xB8 ) * 2 + 3;
00097 break;
00098
00099 default:
00100 p += 1;
00101 break;
00102 }
00103 }
00104
00105 Exit:
00106 FT_UNUSED( error );
00107 FT_FRAME_EXIT();
00108 return result;
00109 }
00110
00111
00112 static FT_Bool
00113 _tt_check_patents_in_table( FT_Face face,
00114 FT_ULong tag )
00115 {
00116 FT_Stream stream = face->stream;
00117 FT_Error error = FT_Err_Ok;
00118 FT_Service_SFNT_Table service;
00119 FT_Bool result = FALSE;
00120
00121
00122 FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
00123
00124 if ( service )
00125 {
00126 FT_UInt i = 0;
00127 FT_ULong tag_i = 0, offset_i = 0, length_i = 0;
00128
00129
00130 for ( i = 0; !error && tag_i != tag ; i++ )
00131 error = service->table_info( face, i,
00132 &tag_i, &offset_i, &length_i );
00133
00134 if ( error ||
00135 FT_STREAM_SEEK( offset_i ) )
00136 goto Exit;
00137
00138 result = _tt_check_patents_in_range( stream, length_i );
00139 }
00140
00141 Exit:
00142 return result;
00143 }
00144
00145
00146 static FT_Bool
00147 _tt_face_check_patents( FT_Face face )
00148 {
00149 FT_Stream stream = face->stream;
00150 FT_UInt gindex;
00151 FT_Error error;
00152 FT_Bool result;
00153
00154 FT_Service_TTGlyf service;
00155
00156
00157 result = _tt_check_patents_in_table( face, TTAG_fpgm );
00158 if ( result )
00159 goto Exit;
00160
00161 result = _tt_check_patents_in_table( face, TTAG_prep );
00162 if ( result )
00163 goto Exit;
00164
00165 FT_FACE_FIND_SERVICE( face, service, TT_GLYF );
00166 if ( service == NULL )
00167 goto Exit;
00168
00169 for ( gindex = 0; gindex < (FT_UInt)face->num_glyphs; gindex++ )
00170 {
00171 FT_ULong offset, num_ins, size;
00172 FT_Int num_contours;
00173
00174
00175 offset = service->get_location( face, gindex, &size );
00176 if ( size == 0 )
00177 continue;
00178
00179 if ( FT_STREAM_SEEK( offset ) ||
00180 FT_READ_SHORT( num_contours ) )
00181 continue;
00182
00183 if ( num_contours >= 0 )
00184 {
00185 if ( FT_STREAM_SKIP( 8 + num_contours * 2 ) )
00186 continue;
00187 }
00188 else
00189 {
00190 FT_Bool has_instr = 0;
00191
00192
00193 if ( FT_STREAM_SKIP( 8 ) )
00194 continue;
00195
00196
00197 for (;;)
00198 {
00199 FT_UInt flags, toskip;
00200
00201
00202 if( FT_READ_USHORT( flags ) )
00203 break;
00204
00205 toskip = 2 + 1 + 1;
00206
00207 if ( ( flags & ( 1 << 0 ) ) != 0 )
00208 toskip += 2;
00209
00210 if ( ( flags & ( 1 << 3 ) ) != 0 )
00211 toskip += 2;
00212 else if ( ( flags & ( 1 << 6 ) ) != 0 )
00213 toskip += 4;
00214 else if ( ( flags & ( 1 << 7 ) ) != 0 )
00215 toskip += 8;
00216
00217 if ( ( flags & ( 1 << 8 ) ) != 0 )
00218 has_instr = 1;
00219
00220 if ( FT_STREAM_SKIP( toskip ) )
00221 goto NextGlyph;
00222
00223 if ( ( flags & ( 1 << 5 ) ) == 0 )
00224 break;
00225 }
00226
00227 if ( !has_instr )
00228 goto NextGlyph;
00229 }
00230
00231 if ( FT_READ_USHORT( num_ins ) )
00232 continue;
00233
00234 result = _tt_check_patents_in_range( stream, num_ins );
00235 if ( result )
00236 goto Exit;
00237
00238 NextGlyph:
00239 ;
00240 }
00241
00242 Exit:
00243 return result;
00244 }
00245
00246
00247
00248
00249 FT_EXPORT_DEF( FT_Bool )
00250 FT_Face_CheckTrueTypePatents( FT_Face face )
00251 {
00252 FT_Bool result = FALSE;
00253
00254
00255 if ( face && FT_IS_SFNT( face ) )
00256 result = _tt_face_check_patents( face );
00257
00258 return result;
00259 }
00260
00261
00262
00263
00264 FT_EXPORT_DEF( FT_Bool )
00265 FT_Face_SetUnpatentedHinting( FT_Face face,
00266 FT_Bool value )
00267 {
00268 FT_Bool result = FALSE;
00269
00270
00271 #if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \
00272 !defined( TT_CONFIG_OPTION_BYTECODE_INTEPRETER )
00273 if ( face && FT_IS_SFNT( face ) )
00274 {
00275 result = !face->internal->ignore_unpatented_hinter;
00276 face->internal->ignore_unpatented_hinter = !value;
00277 }
00278 #else
00279 FT_UNUSED( face );
00280 FT_UNUSED( value );
00281 #endif
00282
00283 return result;
00284 }
00285
00286