ref: 75e7acd8408fa33849fde9ee648d3011946497bd
parent: 5f5e544611fd882d38239d6afccf0c968700895a
author: David Turner <[email protected]>
date: Sun Jun 10 20:26:25 EDT 2007
add missing file, doh !
--- /dev/null
+++ b/src/base/ftpatent.c
@@ -1,0 +1,223 @@
+#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 = 0;
+ 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 = 1;
+ 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 = 1;
+ 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_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_Service_SFNT_Table service;
+ FT_Bool result = 0;
+
+ FT_FACE_FIND_SERVICE( face, service, SFNT_TABLE );
+
+ if (service)
+ {
+ FT_ULong offset, size;
+
+ error = service->table_info( face, tag, &offset, &size );
+ if ( error ||
+ FT_STREAM_SEEK( offset ) )
+ goto Exit;
+
+ result = _tt_check_patents_in_range( stream, size );
+ }
+ 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;
+ }
+
+ FT_EXPORT_DEF( FT_Bool )
+ FT_Face_CheckTrueTypePatents( FT_Face face )
+ {
+ FT_Bool result = 0;
+
+ if ( face && FT_IS_SFNT(face) )
+ {
+ result = _tt_face_check_patents( face );
+ }
+ return result;
+ }