ftpatent.c

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  ftpatent.c                                                             */
00004 /*                                                                         */
00005 /*    FreeType API for checking patented TrueType bytecode instructions    */
00006 /*    (body).                                                              */
00007 /*                                                                         */
00008 /*  Copyright 2007, 2008, 2010 by David Turner.                            */
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 #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:  /* SPvTL // */
00047       case 0x07:  /* SPvTL +  */
00048       case 0x08:  /* SFvTL // */
00049       case 0x09:  /* SFvTL +  */
00050       case 0x0A:  /* SPvFS    */
00051       case 0x0B:  /* SFvFS    */
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:  /* DELTAP2 */
00070       case 0x72:  /* DELTAP3 */
00071       case 0x73:  /* DELTAC0 */
00072       case 0x74:  /* DELTAC1 */
00073       case 0x75:  /* DELTAC2 */
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 )  /* simple glyph */
00184       {
00185         if ( FT_STREAM_SKIP( 8 + num_contours * 2 ) )
00186           continue;
00187       }
00188       else  /* compound glyph */
00189       {
00190         FT_Bool  has_instr = 0;
00191 
00192 
00193         if ( FT_STREAM_SKIP( 8 ) )
00194           continue;
00195 
00196         /* now read each component */
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 )       /* ARGS_ARE_WORDS */
00208             toskip += 2;
00209 
00210           if ( ( flags & ( 1 << 3 ) ) != 0 )       /* WE_HAVE_A_SCALE */
00211             toskip += 2;
00212           else if ( ( flags & ( 1 << 6 ) ) != 0 )  /* WE_HAVE_X_Y_SCALE */
00213             toskip += 4;
00214           else if ( ( flags & ( 1 << 7 ) ) != 0 )  /* WE_HAVE_A_2x2 */
00215             toskip += 8;
00216 
00217           if ( ( flags & ( 1 << 8 ) ) != 0 )       /* WE_HAVE_INSTRUCTIONS */
00218             has_instr = 1;
00219 
00220           if ( FT_STREAM_SKIP( toskip ) )
00221             goto NextGlyph;
00222 
00223           if ( ( flags & ( 1 << 5 ) ) == 0 )       /* MORE_COMPONENTS */
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   /* documentation is in freetype.h */
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   /* documentation is in freetype.h */
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 /* END */

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