summaryrefslogtreecommitdiff
path: root/src/sfnt/sfobjs.c
diff options
context:
space:
mode:
authorNikhil Ramakrishnan <ramakrishnan.nikhil@gmail.com>2019-05-30 23:57:34 +0530
committerNikhil Ramakrishnan <ramakrishnan.nikhil@gmail.com>2019-05-30 23:57:34 +0530
commit7b275a5af161c71a169dcec65f2f6998c9f2d6d5 (patch)
tree0f0566affa6275f33eac1ff70d4259d973073cd1 /src/sfnt/sfobjs.c
parentf0de218cedc693f3dee62fbf045cdd39ac03d12d (diff)
downloadfreetype2-7b275a5af161c71a169dcec65f2f6998c9f2d6d5.tar.gz
[sfnt] Separate WOFF sources and headers.
Move WOFF sources and headers to separate files. * include/freetype/internal/wofftypes.h, src/sfnt/sfwoff.c, src/sfnt/sfwoff.h: New files. * include/freetype/internal/fttrace.h: Register `sfwoff.c'. * include/freetype/internal/internal.h: Define FT_INTERNAL_WOFF_TYPES_H. * include/freetype/internal/sfnt.h: Include FT_INTERNAL_WOFF_TYPES_H. * include/freetype/internal/tttypes.h: Move out WOFF structures. * src/sfnt/rules.mk: Add `sfwoff.c'. * src/sfnt/sfnt.c: Include `sfwoff.c'. * src/sfnt/sfobjs.c: Include `sfwoff.h', move out WOFF sources.
Diffstat (limited to 'src/sfnt/sfobjs.c')
-rw-r--r--src/sfnt/sfobjs.c399
1 files changed, 1 insertions, 398 deletions
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index 0b43d251b..6edf3ae1d 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -21,13 +21,13 @@
#include "ttload.h"
#include "ttcmap.h"
#include "ttkern.h"
+#include "sfwoff.h"
#include FT_INTERNAL_SFNT_H
#include FT_INTERNAL_DEBUG_H
#include FT_TRUETYPE_IDS_H
#include FT_TRUETYPE_TAGS_H
#include FT_SERVICE_POSTSCRIPT_CMAPS_H
#include FT_SFNT_NAMES_H
-#include FT_GZIP_H
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#include FT_SERVICE_MULTIPLE_MASTERS_H
@@ -337,403 +337,6 @@
}
-#define WRITE_USHORT( p, v ) \
- do \
- { \
- *(p)++ = (FT_Byte)( (v) >> 8 ); \
- *(p)++ = (FT_Byte)( (v) >> 0 ); \
- \
- } while ( 0 )
-
-#define WRITE_ULONG( p, v ) \
- do \
- { \
- *(p)++ = (FT_Byte)( (v) >> 24 ); \
- *(p)++ = (FT_Byte)( (v) >> 16 ); \
- *(p)++ = (FT_Byte)( (v) >> 8 ); \
- *(p)++ = (FT_Byte)( (v) >> 0 ); \
- \
- } while ( 0 )
-
-
- static void
- sfnt_stream_close( FT_Stream stream )
- {
- FT_Memory memory = stream->memory;
-
-
- FT_FREE( stream->base );
-
- stream->size = 0;
- stream->base = NULL;
- stream->close = NULL;
- }
-
-
- FT_CALLBACK_DEF( int )
- compare_offsets( const void* a,
- const void* b )
- {
- WOFF_Table table1 = *(WOFF_Table*)a;
- WOFF_Table table2 = *(WOFF_Table*)b;
-
- FT_ULong offset1 = table1->Offset;
- FT_ULong offset2 = table2->Offset;
-
-
- if ( offset1 > offset2 )
- return 1;
- else if ( offset1 < offset2 )
- return -1;
- else
- return 0;
- }
-
-
- /* Replace `face->root.stream' with a stream containing the extracted */
- /* SFNT of a WOFF font. */
-
- static FT_Error
- woff_open_font( FT_Stream stream,
- TT_Face face )
- {
- FT_Memory memory = stream->memory;
- FT_Error error = FT_Err_Ok;
-
- WOFF_HeaderRec woff;
- WOFF_Table tables = NULL;
- WOFF_Table* indices = NULL;
-
- FT_ULong woff_offset;
-
- FT_Byte* sfnt = NULL;
- FT_Stream sfnt_stream = NULL;
-
- FT_Byte* sfnt_header;
- FT_ULong sfnt_offset;
-
- FT_Int nn;
- FT_ULong old_tag = 0;
-
- static const FT_Frame_Field woff_header_fields[] =
- {
-#undef FT_STRUCTURE
-#define FT_STRUCTURE WOFF_HeaderRec
-
- FT_FRAME_START( 44 ),
- FT_FRAME_ULONG ( signature ),
- FT_FRAME_ULONG ( flavor ),
- FT_FRAME_ULONG ( length ),
- FT_FRAME_USHORT( num_tables ),
- FT_FRAME_USHORT( reserved ),
- FT_FRAME_ULONG ( totalSfntSize ),
- FT_FRAME_USHORT( majorVersion ),
- FT_FRAME_USHORT( minorVersion ),
- FT_FRAME_ULONG ( metaOffset ),
- FT_FRAME_ULONG ( metaLength ),
- FT_FRAME_ULONG ( metaOrigLength ),
- FT_FRAME_ULONG ( privOffset ),
- FT_FRAME_ULONG ( privLength ),
- FT_FRAME_END
- };
-
-
- FT_ASSERT( stream == face->root.stream );
- FT_ASSERT( FT_STREAM_POS() == 0 );
-
- if ( FT_STREAM_READ_FIELDS( woff_header_fields, &woff ) )
- return error;
-
- /* Make sure we don't recurse back here or hit TTC code. */
- if ( woff.flavor == TTAG_wOFF || woff.flavor == TTAG_ttcf )
- return FT_THROW( Invalid_Table );
-
- /* Miscellaneous checks. */
- if ( woff.length != stream->size ||
- woff.num_tables == 0 ||
- 44 + woff.num_tables * 20UL >= woff.length ||
- 12 + woff.num_tables * 16UL >= woff.totalSfntSize ||
- ( woff.totalSfntSize & 3 ) != 0 ||
- ( woff.metaOffset == 0 && ( woff.metaLength != 0 ||
- woff.metaOrigLength != 0 ) ) ||
- ( woff.metaLength != 0 && woff.metaOrigLength == 0 ) ||
- ( woff.privOffset == 0 && woff.privLength != 0 ) )
- {
- FT_ERROR(( "woff_font_open: invalid WOFF header\n" ));
- return FT_THROW( Invalid_Table );
- }
-
- /* Don't trust `totalSfntSize' before thorough checks. */
- if ( FT_ALLOC( sfnt, 12 + woff.num_tables * 16UL ) ||
- FT_NEW( sfnt_stream ) )
- goto Exit;
-
- sfnt_header = sfnt;
-
- /* Write sfnt header. */
- {
- FT_UInt searchRange, entrySelector, rangeShift, x;
-
-
- x = woff.num_tables;
- entrySelector = 0;
- while ( x )
- {
- x >>= 1;
- entrySelector += 1;
- }
- entrySelector--;
-
- searchRange = ( 1 << entrySelector ) * 16;
- rangeShift = woff.num_tables * 16 - searchRange;
-
- WRITE_ULONG ( sfnt_header, woff.flavor );
- WRITE_USHORT( sfnt_header, woff.num_tables );
- WRITE_USHORT( sfnt_header, searchRange );
- WRITE_USHORT( sfnt_header, entrySelector );
- WRITE_USHORT( sfnt_header, rangeShift );
- }
-
- /* While the entries in the sfnt header must be sorted by the */
- /* tag value, the tables themselves are not. We thus have to */
- /* sort them by offset and check that they don't overlap. */
-
- if ( FT_NEW_ARRAY( tables, woff.num_tables ) ||
- FT_NEW_ARRAY( indices, woff.num_tables ) )
- goto Exit;
-
- FT_TRACE2(( "\n"
- " tag offset compLen origLen checksum\n"
- " -------------------------------------------\n" ));
-
- if ( FT_FRAME_ENTER( 20L * woff.num_tables ) )
- goto Exit;
-
- for ( nn = 0; nn < woff.num_tables; nn++ )
- {
- WOFF_Table table = tables + nn;
-
- table->Tag = FT_GET_TAG4();
- table->Offset = FT_GET_ULONG();
- table->CompLength = FT_GET_ULONG();
- table->OrigLength = FT_GET_ULONG();
- table->CheckSum = FT_GET_ULONG();
-
- FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx %08lx\n",
- (FT_Char)( table->Tag >> 24 ),
- (FT_Char)( table->Tag >> 16 ),
- (FT_Char)( table->Tag >> 8 ),
- (FT_Char)( table->Tag ),
- table->Offset,
- table->CompLength,
- table->OrigLength,
- table->CheckSum ));
-
- if ( table->Tag <= old_tag )
- {
- FT_FRAME_EXIT();
-
- FT_ERROR(( "woff_font_open: table tags are not sorted\n" ));
- error = FT_THROW( Invalid_Table );
- goto Exit;
- }
-
- old_tag = table->Tag;
- indices[nn] = table;
- }
-
- FT_FRAME_EXIT();
-
- /* Sort by offset. */
-
- ft_qsort( indices,
- woff.num_tables,
- sizeof ( WOFF_Table ),
- compare_offsets );
-
- /* Check offsets and lengths. */
-
- woff_offset = 44 + woff.num_tables * 20L;
- sfnt_offset = 12 + woff.num_tables * 16L;
-
- for ( nn = 0; nn < woff.num_tables; nn++ )
- {
- WOFF_Table table = indices[nn];
-
-
- if ( table->Offset != woff_offset ||
- table->CompLength > woff.length ||
- table->Offset > woff.length - table->CompLength ||
- table->OrigLength > woff.totalSfntSize ||
- sfnt_offset > woff.totalSfntSize - table->OrigLength ||
- table->CompLength > table->OrigLength )
- {
- FT_ERROR(( "woff_font_open: invalid table offsets\n" ));
- error = FT_THROW( Invalid_Table );
- goto Exit;
- }
-
- table->OrigOffset = sfnt_offset;
-
- /* The offsets must be multiples of 4. */
- woff_offset += ( table->CompLength + 3 ) & ~3U;
- sfnt_offset += ( table->OrigLength + 3 ) & ~3U;
- }
-
- /*
- * Final checks!
- *
- * We don't decode and check the metadata block.
- * We don't check table checksums either.
- * But other than those, I think we implement all
- * `MUST' checks from the spec.
- */
-
- if ( woff.metaOffset )
- {
- if ( woff.metaOffset != woff_offset ||
- woff.metaOffset + woff.metaLength > woff.length )
- {
- FT_ERROR(( "woff_font_open:"
- " invalid `metadata' offset or length\n" ));
- error = FT_THROW( Invalid_Table );
- goto Exit;
- }
-
- /* We have padding only ... */
- woff_offset += woff.metaLength;
- }
-
- if ( woff.privOffset )
- {
- /* ... if it isn't the last block. */
- woff_offset = ( woff_offset + 3 ) & ~3U;
-
- if ( woff.privOffset != woff_offset ||
- woff.privOffset + woff.privLength > woff.length )
- {
- FT_ERROR(( "woff_font_open: invalid `private' offset or length\n" ));
- error = FT_THROW( Invalid_Table );
- goto Exit;
- }
-
- /* No padding for the last block. */
- woff_offset += woff.privLength;
- }
-
- if ( sfnt_offset != woff.totalSfntSize ||
- woff_offset != woff.length )
- {
- FT_ERROR(( "woff_font_open: invalid `sfnt' table structure\n" ));
- error = FT_THROW( Invalid_Table );
- goto Exit;
- }
-
- /* Now use `totalSfntSize'. */
- if ( FT_REALLOC( sfnt,
- 12 + woff.num_tables * 16UL,
- woff.totalSfntSize ) )
- goto Exit;
-
- sfnt_header = sfnt + 12;
-
- /* Write the tables. */
-
- for ( nn = 0; nn < woff.num_tables; nn++ )
- {
- WOFF_Table table = tables + nn;
-
-
- /* Write SFNT table entry. */
- WRITE_ULONG( sfnt_header, table->Tag );
- WRITE_ULONG( sfnt_header, table->CheckSum );
- WRITE_ULONG( sfnt_header, table->OrigOffset );
- WRITE_ULONG( sfnt_header, table->OrigLength );
-
- /* Write table data. */
- if ( FT_STREAM_SEEK( table->Offset ) ||
- FT_FRAME_ENTER( table->CompLength ) )
- goto Exit;
-
- if ( table->CompLength == table->OrigLength )
- {
- /* Uncompressed data; just copy. */
- ft_memcpy( sfnt + table->OrigOffset,
- stream->cursor,
- table->OrigLength );
- }
- else
- {
-#ifdef FT_CONFIG_OPTION_USE_ZLIB
-
- /* Uncompress with zlib. */
- FT_ULong output_len = table->OrigLength;
-
-
- error = FT_Gzip_Uncompress( memory,
- sfnt + table->OrigOffset, &output_len,
- stream->cursor, table->CompLength );
- if ( error )
- goto Exit;
- if ( output_len != table->OrigLength )
- {
- FT_ERROR(( "woff_font_open: compressed table length mismatch\n" ));
- error = FT_THROW( Invalid_Table );
- goto Exit;
- }
-
-#else /* !FT_CONFIG_OPTION_USE_ZLIB */
-
- error = FT_THROW( Unimplemented_Feature );
- goto Exit;
-
-#endif /* !FT_CONFIG_OPTION_USE_ZLIB */
- }
-
- FT_FRAME_EXIT();
-
- /* We don't check whether the padding bytes in the WOFF file are */
- /* actually '\0'. For the output, however, we do set them properly. */
- sfnt_offset = table->OrigOffset + table->OrigLength;
- while ( sfnt_offset & 3 )
- {
- sfnt[sfnt_offset] = '\0';
- sfnt_offset++;
- }
- }
-
- /* Ok! Finally ready. Swap out stream and return. */
- FT_Stream_OpenMemory( sfnt_stream, sfnt, woff.totalSfntSize );
- sfnt_stream->memory = stream->memory;
- sfnt_stream->close = sfnt_stream_close;
-
- FT_Stream_Free(
- face->root.stream,
- ( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
-
- face->root.stream = sfnt_stream;
-
- face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
-
- Exit:
- FT_FREE( tables );
- FT_FREE( indices );
-
- if ( error )
- {
- FT_FREE( sfnt );
- FT_Stream_Close( sfnt_stream );
- FT_FREE( sfnt_stream );
- }
-
- return error;
- }
-
-
-#undef WRITE_USHORT
-#undef WRITE_ULONG
-
-
/* Fill in face->ttc_header. If the font is not a TTC, it is */
/* synthesized into a TTC with one offset table. */
static FT_Error