summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikhil Ramakrishnan <ramakrishnan.nikhil@gmail.com>2019-06-30 04:31:04 +0530
committerNikhil Ramakrishnan <ramakrishnan.nikhil@gmail.com>2019-06-30 04:36:44 +0530
commitf6c4d58ec8340051051311ef4781089a9e56d17c (patch)
treedcd64fe623f1b98a68e2b8caefecc921e692f04f
parent6d3d309ae62d2153444c53601da1ff4b3c7a57db (diff)
downloadfreetype2-f6c4d58ec8340051051311ef4781089a9e56d17c.tar.gz
Uncompress Brotli streams and face_index support.
WOFF2 compressed stream is now uncompressed if Brotli is available. This data is stored in a separate buffer (uncompressed_buf) because it does not contain direct table data. Certain tables have transformations applied to them, and they must be reconstructed before we can write those tables to the SFNT stream. `face_index' is now being passed as a parameter to `woff2_open_font'. * src/sfnt/sfobjs.c (sfnt_open_font): Add parameter `face_instance_index'. * src/sfnt/sfwoff2.c (woff2_uncompress): New function. (woff2_open_font): Call `woff2_uncompress'. * src/sfnt/sfwoff2.h (woff2_open_font): Modify declaration.
-rw-r--r--src/sfnt/sfobjs.c7
-rw-r--r--src/sfnt/sfwoff2.c74
-rw-r--r--src/sfnt/sfwoff2.h3
3 files changed, 73 insertions, 11 deletions
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index b5a6523cf..67b917822 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -342,7 +342,8 @@
/* synthesized into a TTC with one offset table. */
static FT_Error
sfnt_open_font( FT_Stream stream,
- TT_Face face )
+ TT_Face face,
+ FT_Int face_instance_index )
{
FT_Memory memory = stream->memory;
FT_Error error;
@@ -393,7 +394,7 @@
if ( FT_STREAM_SEEK( offset ) )
return error;
- error = woff2_open_font( stream, face );
+ error = woff2_open_font( stream, face, face_instance_index );
if ( error )
return error;
@@ -531,7 +532,7 @@
FT_TRACE2(( "SFNT driver\n" ));
- error = sfnt_open_font( stream, face );
+ error = sfnt_open_font( stream, face, face_instance_index );
if ( error )
return error;
diff --git a/src/sfnt/sfwoff2.c b/src/sfnt/sfwoff2.c
index 8a5f7c5b3..ec3060200 100644
--- a/src/sfnt/sfwoff2.c
+++ b/src/sfnt/sfwoff2.c
@@ -23,6 +23,13 @@
#include FT_INTERNAL_STREAM_H
+#ifdef FT_CONFIG_OPTION_USE_BROTLI
+
+#include <brotli/decode.h>
+
+#endif
+
+
/**************************************************************************
*
* The macro FT_COMPONENT is used in trace mode. It is an implicit
@@ -96,7 +103,7 @@
return FT_THROW( Invalid_Table );
if( code == wordCode )
{
- /* Read next two bytes and store UInt16 value */
+ /* Read next two bytes and store FT_UShort value */
if( FT_READ_USHORT( result_short ) )
return FT_THROW( Invalid_Table );
*value = result_short;
@@ -176,7 +183,7 @@
}
- static FT_Error
+ static FT_UInt64
compute_first_table_offset( const WOFF2_Header woff2 )
{
FT_Int nn;
@@ -196,12 +203,42 @@
}
+ static FT_Error
+ woff2_uncompress( FT_Byte* dst,
+ FT_ULong dst_size,
+ const FT_Byte* src,
+ FT_ULong src_size )
+ {
+#ifdef FT_CONFIG_OPTION_USE_BROTLI
+
+ FT_ULong uncompressed_size = dst_size;
+ BrotliDecoderResult result;
+
+ result = BrotliDecoderDecompress(
+ src_size, src, &uncompressed_size, dst);
+
+ if( result != BROTLI_DECODER_RESULT_SUCCESS ||
+ uncompressed_size != dst_size )
+ return FT_THROW( Invalid_Table );
+
+ return FT_Err_Ok;
+
+#else /* !FT_CONFIG_OPTION_USE_BROTLI */
+
+ FT_ERROR(( "woff2_uncompress: Brotli support not available.\n" ));
+ return FT_THROW( Unimplemented_Feature );
+
+#endif /* !FT_CONFIG_OPTION_USE_BROTLI */
+ }
+
+
/* Replace `face->root.stream' with a stream containing the extracted */
/* SFNT of a WOFF2 font. */
FT_LOCAL_DEF( FT_Error )
woff2_open_font( FT_Stream stream,
- TT_Face face )
+ TT_Face face,
+ FT_Int face_index )
{
FT_Memory memory = stream->memory;
FT_Error error = FT_Err_Ok;
@@ -227,6 +264,8 @@
FT_Stream sfnt_stream = NULL;
FT_Byte* sfnt_header;
+ FT_Byte* uncompressed_buf = NULL;
+
static const FT_Frame_Field woff2_header_fields[] =
{
#undef FT_STRUCTURE
@@ -256,7 +295,7 @@
FT_ASSERT( FT_STREAM_POS() == 0 );
/* DEBUG - Remove later. */
- FT_TRACE2(( "Face index = %ld\n", face->root.face_index ));
+ FT_TRACE2(( "Face index = %ld\n", face_index ));
/* Read WOFF2 Header. */
if ( FT_STREAM_READ_FIELDS( woff2_header_fields, &woff2 ) )
@@ -306,7 +345,6 @@
" tag flags transform origLen transformLen\n"
" --------------------------------------------------\n" ));
- /* TODO check whether there is sufficient input before FT_READ_*. */
for ( nn = 0; nn < woff2.num_tables; nn++ )
{
WOFF2_Table table = tables + nn;
@@ -455,7 +493,7 @@
return FT_THROW( Invalid_Table );
/* DEBUG - Remove later */
else
- FT_TRACE2(( "glyf and loca are valid.\n" ));
+ FT_TRACE2(( "glyf and loca indices are valid.\n" ));
}
}
/* Collection directory reading complete. */
@@ -470,7 +508,7 @@
file_offset = ROUND4( woff2.compressed_offset +
woff2.totalCompressedSize );
- /* Few more checks before we start reading the tables */
+ /* Few more checks before we start reading the tables. */
if( file_offset > woff2.length )
return FT_THROW( Invalid_Table );
@@ -491,6 +529,7 @@
if( file_offset != ( ROUND4( woff2.length ) ) )
return FT_THROW( Invalid_Table );
+ /* TODO Add support for uncompression of TTC fonts. */
/* Redirect a TTC to exit for now. */
if( woff2.header_version )
{
@@ -551,6 +590,27 @@
(FT_Char)( table->Tag )));
}
+ if( woff2.uncompressed_size < 1 )
+ {
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+
+ /* Allocate memory for uncompressed table data. */
+ if ( FT_ALLOC( uncompressed_buf, woff2.uncompressed_size ) ||
+ FT_FRAME_ENTER( woff2.totalCompressedSize ) )
+ goto Exit;
+
+ /* Uncompress the stream. */
+ error = woff2_uncompress( uncompressed_buf, woff2.uncompressed_size,
+ stream->cursor, woff2.totalCompressedSize );
+ if( error )
+ goto Exit;
+
+ FT_FRAME_EXIT();
+
+ /* TODO Write table entries. */
+
error = FT_THROW( Unimplemented_Feature );
/* DEBUG - Remove later */
FT_TRACE2(( "Reached end without errors.\n" ));
diff --git a/src/sfnt/sfwoff2.h b/src/sfnt/sfwoff2.h
index 5c3cc3d72..f7e7f43f6 100644
--- a/src/sfnt/sfwoff2.h
+++ b/src/sfnt/sfwoff2.h
@@ -30,7 +30,8 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
woff2_open_font( FT_Stream stream,
- TT_Face face );
+ TT_Face face,
+ FT_Int face_index );
FT_END_HEADER