misc/libfreetype/src/base/ftpatent.c
changeset 5172 88f2e05288ba
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/misc/libfreetype/src/base/ftpatent.c	Mon Apr 25 01:46:54 2011 +0200
@@ -0,0 +1,286 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftpatent.c                                                             */
+/*                                                                         */
+/*    FreeType API for checking patented TrueType bytecode instructions    */
+/*    (body).                                                              */
+/*                                                                         */
+/*  Copyright 2007, 2008, 2010 by David Turner.                            */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_TRUETYPE_TAGS_H
+#include FT_INTERNAL_OBJECTS_H
+#include FT_INTERNAL_STREAM_H
+#include FT_SERVICE_SFNT_H
+#include FT_SERVICE_TRUETYPE_GLYF_H
+
+
+  static FT_Bool
+  _tt_check_patents_in_range( FT_Stream  stream,
+                              FT_ULong   size )
+  {
+    FT_Bool   result = FALSE;
+    FT_Error  error;
+    FT_Bytes  p, end;
+
+
+    if ( FT_FRAME_ENTER( size ) )
+      return 0;
+
+    p   = stream->cursor;
+    end = p + size;
+
+    while ( p < end )
+    {
+      switch (p[0])
+      {
+      case 0x06:  /* SPvTL // */
+      case 0x07:  /* SPvTL +  */
+      case 0x08:  /* SFvTL // */
+      case 0x09:  /* SFvTL +  */
+      case 0x0A:  /* SPvFS    */
+      case 0x0B:  /* SFvFS    */
+        result = TRUE;
+        goto Exit;
+
+      case 0x40:
+        if ( p + 1 >= end )
+          goto Exit;
+
+        p += p[1] + 2;
+        break;
+
+      case 0x41:
+        if ( p + 1 >= end )
+          goto Exit;
+
+        p += p[1] * 2 + 2;
+        break;
+
+      case 0x71:  /* DELTAP2 */
+      case 0x72:  /* DELTAP3 */
+      case 0x73:  /* DELTAC0 */
+      case 0x74:  /* DELTAC1 */
+      case 0x75:  /* DELTAC2 */
+        result = TRUE;
+        goto Exit;
+
+      case 0xB0:
+      case 0xB1:
+      case 0xB2:
+      case 0xB3:
+      case 0xB4:
+      case 0xB5:
+      case 0xB6:
+      case 0xB7:
+        p += ( p[0] - 0xB0 ) + 2;
+        break;
+
+      case 0xB8:
+      case 0xB9:
+      case 0xBA:
+      case 0xBB:
+      case 0xBC:
+      case 0xBD:
+      case 0xBE:
+      case 0xBF:
+        p += ( p[0] - 0xB8 ) * 2 + 3;
+        break;
+
+      default:
+        p += 1;
+        break;
+      }
+    }
+
+  Exit:
+    FT_UNUSED( error );
+    FT_FRAME_EXIT();
+    return result;
+  }
+
+
+  static FT_Bool
+  _tt_check_patents_in_table( FT_Face   face,
+                              FT_ULong  tag )
+  {
+    FT_Stream              stream = face->stream;
+    FT_Error               error  = FT_Err_Ok;
+    FT_Service_SFNT_Table  service;
+    FT_Bool                result = FALSE;
+
+
+    FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
+
+    if ( service )
+    {
+      FT_UInt   i = 0;
+      FT_ULong  tag_i = 0, offset_i = 0, length_i = 0;
+
+
+      for ( i = 0; !error && tag_i != tag ; i++ )
+        error = service->table_info( face, i,
+                                     &tag_i, &offset_i, &length_i );
+
+      if ( error                      ||
+           FT_STREAM_SEEK( offset_i ) )
+        goto Exit;
+
+      result = _tt_check_patents_in_range( stream, length_i );
+    }
+
+  Exit:
+    return result;
+  }
+
+
+  static FT_Bool
+  _tt_face_check_patents( FT_Face  face )
+  {
+    FT_Stream  stream = face->stream;
+    FT_UInt    gindex;
+    FT_Error   error;
+    FT_Bool    result;
+
+    FT_Service_TTGlyf  service;
+
+
+    result = _tt_check_patents_in_table( face, TTAG_fpgm );
+    if ( result )
+      goto Exit;
+
+    result = _tt_check_patents_in_table( face, TTAG_prep );
+    if ( result )
+      goto Exit;
+
+    FT_FACE_FIND_SERVICE( face, service, TT_GLYF );
+    if ( service == NULL )
+      goto Exit;
+
+    for ( gindex = 0; gindex < (FT_UInt)face->num_glyphs; gindex++ )
+    {
+      FT_ULong  offset, num_ins, size;
+      FT_Int    num_contours;
+
+
+      offset = service->get_location( face, gindex, &size );
+      if ( size == 0 )
+        continue;
+
+      if ( FT_STREAM_SEEK( offset )      ||
+           FT_READ_SHORT( num_contours ) )
+        continue;
+
+      if ( num_contours >= 0 )  /* simple glyph */
+      {
+        if ( FT_STREAM_SKIP( 8 + num_contours * 2 ) )
+          continue;
+      }
+      else  /* compound glyph */
+      {
+        FT_Bool  has_instr = 0;
+
+
+        if ( FT_STREAM_SKIP( 8 ) )
+          continue;
+
+        /* now read each component */
+        for (;;)
+        {
+          FT_UInt  flags, toskip;
+
+
+          if( FT_READ_USHORT( flags ) )
+            break;
+
+          toskip = 2 + 1 + 1;
+
+          if ( ( flags & ( 1 << 0 ) ) != 0 )       /* ARGS_ARE_WORDS */
+            toskip += 2;
+
+          if ( ( flags & ( 1 << 3 ) ) != 0 )       /* WE_HAVE_A_SCALE */
+            toskip += 2;
+          else if ( ( flags & ( 1 << 6 ) ) != 0 )  /* WE_HAVE_X_Y_SCALE */
+            toskip += 4;
+          else if ( ( flags & ( 1 << 7 ) ) != 0 )  /* WE_HAVE_A_2x2 */
+            toskip += 8;
+
+          if ( ( flags & ( 1 << 8 ) ) != 0 )       /* WE_HAVE_INSTRUCTIONS */
+            has_instr = 1;
+
+          if ( FT_STREAM_SKIP( toskip ) )
+            goto NextGlyph;
+
+          if ( ( flags & ( 1 << 5 ) ) == 0 )       /* MORE_COMPONENTS */
+            break;
+        }
+
+        if ( !has_instr )
+          goto NextGlyph;
+      }
+
+      if ( FT_READ_USHORT( num_ins ) )
+        continue;
+
+      result = _tt_check_patents_in_range( stream, num_ins );
+      if ( result )
+        goto Exit;
+
+    NextGlyph:
+      ;
+    }
+
+  Exit:
+    return result;
+  }
+
+
+  /* documentation is in freetype.h */
+
+  FT_EXPORT_DEF( FT_Bool )
+  FT_Face_CheckTrueTypePatents( FT_Face  face )
+  {
+    FT_Bool  result = FALSE;
+
+
+    if ( face && FT_IS_SFNT( face ) )
+      result = _tt_face_check_patents( face );
+
+    return result;
+  }
+
+
+  /* documentation is in freetype.h */
+
+  FT_EXPORT_DEF( FT_Bool )
+  FT_Face_SetUnpatentedHinting( FT_Face  face,
+                                FT_Bool  value )
+  {
+    FT_Bool  result = FALSE;
+
+
+#if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \
+    !defined( TT_CONFIG_OPTION_BYTECODE_INTEPRETER )
+    if ( face && FT_IS_SFNT( face ) )
+    {
+      result = !face->internal->ignore_unpatented_hinter;
+      face->internal->ignore_unpatented_hinter = !value;
+    }
+#else
+    FT_UNUSED( face );
+    FT_UNUSED( value );
+#endif
+
+    return result;
+  }
+
+/* END */