[woff2] Formatting; some comments.

This commit is contained in:
Werner Lemberg 2019-08-27 10:08:01 +02:00
parent 86803acd2a
commit 60c52f0edb
6 changed files with 283 additions and 181 deletions

View File

@ -478,7 +478,7 @@ if test x"$with_png" = xyes -o x"$with_png" = xauto; then
libpng_libsstaticconf="$LIBPNG_LIBS" libpng_libsstaticconf="$LIBPNG_LIBS"
have_libpng="yes (LIBPNG_CFLAGS and LIBPNG_LIBS)" have_libpng="yes (LIBPNG_CFLAGS and LIBPNG_LIBS)"
else else
# fall back to config script. # fall back to config script
AC_MSG_CHECKING([for libpng-config]) AC_MSG_CHECKING([for libpng-config])
if which libpng-config > /dev/null 2>&1; then if which libpng-config > /dev/null 2>&1; then
LIBPNG_CFLAGS=`libpng-config --cflags` LIBPNG_CFLAGS=`libpng-config --cflags`
@ -547,7 +547,7 @@ fi
AC_ARG_WITH([brotli], AC_ARG_WITH([brotli],
[AS_HELP_STRING([--with-brotli=@<:@yes|no|auto@:>@], [AS_HELP_STRING([--with-brotli=@<:@yes|no|auto@:>@],
[Support decompression of WOFF2 streams @<:@default=auto@:>@])], [support decompression of WOFF2 streams @<:@default=auto@:>@])],
[], [with_brotli=auto]) [], [with_brotli=auto])
have_brotli=no have_brotli=no
@ -576,7 +576,7 @@ if test x"$with_brotli" = xyes -o x"$with_brotli" = xauto; then
have_brotli="yes (BROTLI_CFLAGS and BROTLI_LIBS)" have_brotli="yes (BROTLI_CFLAGS and BROTLI_LIBS)"
else else
# since Brotli is quite a new library we don't fall back to a # since Brotli is quite a new library we don't fall back to a
# different test; # different test
: :
fi fi
fi fi
@ -1032,7 +1032,7 @@ if test "x$PYTHON" != "xmissing"; then
fi fi
# entries in Requires.private are separated by commas; # entries in Requires.private are separated by commas
REQUIRES_PRIVATE="$zlib_reqpriv, \ REQUIRES_PRIVATE="$zlib_reqpriv, \
$bzip2_reqpriv, \ $bzip2_reqpriv, \
$libpng_reqpriv, \ $libpng_reqpriv, \

View File

@ -275,13 +275,13 @@ FT_BEGIN_HEADER
* *
* @fields: * @fields:
* x :: * x ::
* x-coordinate. * x-coordinate of point.
* *
* y :: * y ::
* y-coordinate. * y-coordinate of point.
* *
* on_curve :: * on_curve ::
* Whether point is on-curve. * Set if point is on-curve.
*/ */
typedef struct WOFF2_PointRec_ typedef struct WOFF2_PointRec_
{ {

View File

@ -28,20 +28,20 @@ SFNT_COMPILE := $(CC) $(ANSIFLAGS) \
# SFNT driver sources (i.e., C files) # SFNT driver sources (i.e., C files)
# #
SFNT_DRV_SRC := $(SFNT_DIR)/pngshim.c \ SFNT_DRV_SRC := $(SFNT_DIR)/pngshim.c \
$(SFNT_DIR)/sfdriver.c \ $(SFNT_DIR)/sfdriver.c \
$(SFNT_DIR)/sfobjs.c \ $(SFNT_DIR)/sfobjs.c \
$(SFNT_DIR)/sfwoff.c \ $(SFNT_DIR)/sfwoff.c \
$(SFNT_DIR)/sfwoff2.c \ $(SFNT_DIR)/sfwoff2.c \
$(SFNT_DIR)/ttbdf.c \ $(SFNT_DIR)/ttbdf.c \
$(SFNT_DIR)/ttcmap.c \ $(SFNT_DIR)/ttcmap.c \
$(SFNT_DIR)/ttcolr.c \ $(SFNT_DIR)/ttcolr.c \
$(SFNT_DIR)/ttcpal.c \ $(SFNT_DIR)/ttcpal.c \
$(SFNT_DIR)/ttkern.c \ $(SFNT_DIR)/ttkern.c \
$(SFNT_DIR)/ttload.c \ $(SFNT_DIR)/ttload.c \
$(SFNT_DIR)/ttmtx.c \ $(SFNT_DIR)/ttmtx.c \
$(SFNT_DIR)/ttpost.c \ $(SFNT_DIR)/ttpost.c \
$(SFNT_DIR)/ttsbit.c \ $(SFNT_DIR)/ttsbit.c \
$(SFNT_DIR)/woff2tags.c $(SFNT_DIR)/woff2tags.c
# SFNT driver headers # SFNT driver headers

View File

@ -130,17 +130,17 @@
static const FT_Int wordCode = 253; static const FT_Int wordCode = 253;
static const FT_Int lowestUCode = 253; static const FT_Int lowestUCode = 253;
FT_Error error = FT_Err_Ok; FT_Error error = FT_Err_Ok;
FT_Byte code; FT_Byte code;
FT_Byte result_byte = 0; FT_Byte result_byte = 0;
FT_UShort result_short = 0; FT_UShort result_short = 0;
if ( FT_READ_BYTE( code ) ) if ( FT_READ_BYTE( code ) )
return error; return error;
if ( code == wordCode ) if ( code == wordCode )
{ {
/* Read next two bytes and store FT_UShort value */ /* Read next two bytes and store `FT_UShort' value. */
if ( FT_READ_USHORT( result_short ) ) if ( FT_READ_USHORT( result_short ) )
return error; return error;
*value = result_short; *value = result_short;
@ -201,11 +201,13 @@
return FT_Err_Ok; return FT_Err_Ok;
} }
} }
/* Make sure not to exceed the size bound. */ /* Make sure not to exceed the size bound. */
return FT_THROW( Invalid_Table ); return FT_THROW( Invalid_Table );
} }
/* Extend memory of `dst_bytes' buffer and copy data from `src'. */
static FT_Error static FT_Error
write_buf( FT_Byte** dst_bytes, write_buf( FT_Byte** dst_bytes,
FT_ULong* dst_size, FT_ULong* dst_size,
@ -248,6 +250,7 @@
} }
/* Pad buffer to closest multiple of 4. */
static FT_Error static FT_Error
pad4( FT_Byte** sfnt_bytes, pad4( FT_Byte** sfnt_bytes,
FT_ULong* sfnt_size, FT_ULong* sfnt_size,
@ -277,6 +280,7 @@
} }
/* Calculate table checksum of `buf'. */
static FT_Long static FT_Long
compute_ULong_sum( FT_Byte* buf, compute_ULong_sum( FT_Byte* buf,
FT_ULong size ) FT_ULong size )
@ -288,10 +292,10 @@
for ( i = 0; i < aligned_size; i += 4 ) for ( i = 0; i < aligned_size; i += 4 )
{ checksum += ( buf[i ] << 24 ) |
checksum += ( buf[i] << 24 ) | ( buf[i+1] << 16 ) | ( buf[i + 1] << 16 ) |
( buf[i+2] << 8 ) | ( buf[i+3] << 0 ); ( buf[i + 2] << 8 ) |
} ( buf[i + 3] << 0 );
/* If size is not aligned to 4, treat as if it is padded with 0s. */ /* If size is not aligned to 4, treat as if it is padded with 0s. */
if ( size != aligned_size ) if ( size != aligned_size )
@ -301,6 +305,7 @@
v |= buf[i] << ( 24 - 8 * ( i & 3 ) ); v |= buf[i] << ( 24 - 8 * ( i & 3 ) );
checksum += v; checksum += v;
} }
return checksum; return checksum;
} }
@ -317,8 +322,10 @@
BrotliDecoderResult result; BrotliDecoderResult result;
result = BrotliDecoderDecompress( result = BrotliDecoderDecompress( src_size,
src_size, src, &uncompressed_size, dst); src,
&uncompressed_size,
dst );
if ( result != BROTLI_DECODER_RESULT_SUCCESS || if ( result != BROTLI_DECODER_RESULT_SUCCESS ||
uncompressed_size != dst_size ) uncompressed_size != dst_size )
@ -344,7 +351,7 @@
FT_UShort num_tables, FT_UShort num_tables,
FT_ULong tag ) FT_ULong tag )
{ {
FT_Int i; FT_Int i;
for ( i = 0; i < num_tables; i++ ) for ( i = 0; i < num_tables; i++ )
@ -356,7 +363,7 @@
} }
/* Read `numberOfHMetrics' from `hhea' table. */ /* Read `numberOfHMetrics' field from `hhea' table. */
static FT_Error static FT_Error
read_num_hmetrics( FT_Stream stream, read_num_hmetrics( FT_Stream stream,
FT_ULong table_len, FT_ULong table_len,
@ -378,6 +385,7 @@
} }
/* An auxiliary function for overflow-safe addition. */
static FT_Int static FT_Int
with_sign( FT_Byte flag, with_sign( FT_Byte flag,
FT_Int base_val ) FT_Int base_val )
@ -387,6 +395,7 @@
} }
/* An auxiliary function for overflow-safe addition. */
static FT_Int static FT_Int
safe_int_addition( FT_Int a, safe_int_addition( FT_Int a,
FT_Int b, FT_Int b,
@ -401,6 +410,12 @@
} }
/*
* Decode variable-length (flag, xCoordinate, yCoordinate) triplet for a
* simple glyph. See
*
* https://www.w3.org/TR/WOFF2/#triplet_decoding
*/
static FT_Error static FT_Error
triplet_decode( const FT_Byte* flags_in, triplet_decode( const FT_Byte* flags_in,
const FT_Byte* in, const FT_Byte* in,
@ -426,7 +441,7 @@
for ( i = 0; i < n_points; ++i ) for ( i = 0; i < n_points; ++i )
{ {
FT_Byte flag = flags_in[i]; FT_Byte flag = flags_in[i];
FT_Bool on_curve = !( flag >> 7 ); FT_Bool on_curve = !( flag >> 7 );
@ -453,9 +468,10 @@
} }
else if ( flag < 20 ) else if ( flag < 20 )
{ {
dx = with_sign( flag, dx = with_sign( flag,
( ( ( flag - 10 ) & 14 ) << 7 ) + in[triplet_index] ); ( ( ( flag - 10 ) & 14 ) << 7 ) +
dy = 0; in[triplet_index] );
dy = 0;
} }
else if ( flag < 84 ) else if ( flag < 84 )
{ {
@ -473,7 +489,7 @@
1 + ( ( b0 / 12 ) << 8 ) + in[triplet_index] ); 1 + ( ( b0 / 12 ) << 8 ) + in[triplet_index] );
dy = with_sign( flag >> 1, dy = with_sign( flag >> 1,
1 + ( ( ( b0 % 12 ) >> 2 ) << 8 ) + 1 + ( ( ( b0 % 12 ) >> 2 ) << 8 ) +
in[triplet_index + 1] ); in[triplet_index + 1] );
} }
else if ( flag < 124 ) else if ( flag < 124 )
{ {
@ -487,11 +503,12 @@
{ {
dx = with_sign( flag, dx = with_sign( flag,
( in[triplet_index] << 8 ) + ( in[triplet_index] << 8 ) +
in[triplet_index + 1] ); in[triplet_index + 1] );
dy = with_sign( flag >> 1, dy = with_sign( flag >> 1,
( in[triplet_index + 2] << 8 ) + ( in[triplet_index + 2] << 8 ) +
in[triplet_index + 3] ); in[triplet_index + 3] );
} }
triplet_index += data_bytes; triplet_index += data_bytes;
if ( safe_int_addition( x, dx, &x ) ) if ( safe_int_addition( x, dx, &x ) )
@ -504,11 +521,13 @@
result[i].y = y; result[i].y = y;
result[i].on_curve = on_curve; result[i].on_curve = on_curve;
} }
*in_bytes_used = triplet_index; *in_bytes_used = triplet_index;
return FT_Err_Ok; return FT_Err_Ok;
} }
/* Store decoded points in glyph buffer. */
static FT_Error static FT_Error
store_points( FT_ULong n_points, store_points( FT_ULong n_points,
const WOFF2_Point points, const WOFF2_Point points,
@ -536,9 +555,9 @@
{ {
const WOFF2_PointRec point = points[i]; const WOFF2_PointRec point = points[i];
FT_Int flag = point.on_curve ? GLYF_ON_CURVE : 0; FT_Int flag = point.on_curve ? GLYF_ON_CURVE : 0;
FT_Int dx = point.x - last_x; FT_Int dx = point.x - last_x;
FT_Int dy = point.y - last_y; FT_Int dy = point.y - last_y;
if ( dx == 0 ) if ( dx == 0 )
@ -579,10 +598,11 @@
return FT_THROW( Invalid_Table ); return FT_THROW( Invalid_Table );
dst[flag_offset++] = flag; dst[flag_offset++] = flag;
repeat_count = 0; repeat_count = 0;
} }
last_x = point.x;
last_y = point.y; last_x = point.x;
last_y = point.y;
last_flag = flag; last_flag = flag;
} }
@ -604,12 +624,15 @@
y_offset = flag_offset + x_bytes; y_offset = flag_offset + x_bytes;
last_x = 0; last_x = 0;
last_y = 0; last_y = 0;
for ( i = 0; i < n_points; ++i ) for ( i = 0; i < n_points; ++i )
{ {
FT_Int dx = points[i].x - last_x; FT_Int dx = points[i].x - last_x;
FT_Int dy = points[i].y - last_y; FT_Int dy = points[i].y - last_y;
if ( dx == 0 ) {;}
if ( dx == 0 )
;
else if ( dx > -256 && dx < 256 ) else if ( dx > -256 && dx < 256 )
dst[x_offset++] = FT_ABS( dx ); dst[x_offset++] = FT_ABS( dx );
else else
@ -621,7 +644,8 @@
last_x += dx; last_x += dx;
if ( dy == 0 ) {;} if ( dy == 0 )
;
else if ( dy > -256 && dy < 256 ) else if ( dy > -256 && dy < 256 )
dst[y_offset++] = FT_ABS( dy ); dst[y_offset++] = FT_ABS( dy );
else else
@ -662,10 +686,12 @@
x_max = points[0].x; x_max = points[0].x;
y_max = points[0].y; y_max = points[0].y;
} }
for ( i = 1; i < n_points; ++i ) for ( i = 1; i < n_points; ++i )
{ {
FT_Int x = points[i].x; FT_Int x = points[i].x;
FT_Int y = points[i].y; FT_Int y = points[i].y;
x_min = FT_MIN( x, x_min ); x_min = FT_MIN( x, x_min );
y_min = FT_MIN( y, y_min ); y_min = FT_MIN( y, y_min );
@ -674,8 +700,9 @@
} }
/* Write values to `glyf' record. */ /* Write values to `glyf' record. */
offset = 2; offset = 2;
pointer = dst + offset; pointer = dst + offset;
WRITE_SHORT( pointer, x_min ); WRITE_SHORT( pointer, x_min );
WRITE_SHORT( pointer, y_min ); WRITE_SHORT( pointer, y_min );
WRITE_SHORT( pointer, x_max ); WRITE_SHORT( pointer, x_max );
@ -703,6 +730,7 @@
{ {
FT_ULong arg_size; FT_ULong arg_size;
if ( FT_READ_USHORT( flags ) ) if ( FT_READ_USHORT( flags ) )
goto Exit; goto Exit;
we_have_inst |= ( flags & FLAG_WE_HAVE_INSTRUCTIONS ) != 0; we_have_inst |= ( flags & FLAG_WE_HAVE_INSTRUCTIONS ) != 0;
@ -732,6 +760,7 @@
} }
/* Store loca values (provided by `reconstruct_glyf') to output stream. */
static FT_Error static FT_Error
store_loca( FT_ULong* loca_values, store_loca( FT_ULong* loca_values,
FT_ULong loca_values_size, FT_ULong loca_values_size,
@ -749,7 +778,7 @@
FT_Byte* loca_buf = NULL; FT_Byte* loca_buf = NULL;
FT_Byte* dst = NULL; FT_Byte* dst = NULL;
FT_Int i = 0; FT_Int i = 0;
FT_ULong loca_buf_size; FT_ULong loca_buf_size;
const FT_ULong offset_size = index_format ? 4 : 2; const FT_ULong offset_size = index_format ? 4 : 2;
@ -775,7 +804,7 @@
} }
*checksum = compute_ULong_sum( loca_buf, loca_buf_size ); *checksum = compute_ULong_sum( loca_buf, loca_buf_size );
/* Write loca table to sfnt buffer. */ /* Write `loca' table to sfnt buffer. */
if ( WRITE_SFNT_BUF( loca_buf, loca_buf_size ) ) if ( WRITE_SFNT_BUF( loca_buf, loca_buf_size ) )
goto Fail; goto Fail;
@ -811,10 +840,10 @@
FT_Error error = FT_Err_Ok; FT_Error error = FT_Err_Ok;
FT_Byte* sfnt = *sfnt_bytes; FT_Byte* sfnt = *sfnt_bytes;
/* Current position in stream */ /* current position in stream */
const FT_ULong pos = FT_STREAM_POS(); const FT_ULong pos = FT_STREAM_POS();
FT_UInt num_substreams = 7; FT_UInt num_substreams = 7;
FT_UShort num_glyphs; FT_UShort num_glyphs;
FT_UShort index_format; FT_UShort index_format;
@ -831,10 +860,10 @@
WOFF2_Substream substreams = NULL; WOFF2_Substream substreams = NULL;
FT_ULong* loca_values = NULL; FT_ULong* loca_values = NULL;
FT_UShort* n_points_arr = NULL; FT_UShort* n_points_arr = NULL;
FT_Byte* glyph_buf = NULL; FT_Byte* glyph_buf = NULL;
WOFF2_Point points = NULL; WOFF2_Point points = NULL;
if ( FT_NEW_ARRAY( substreams, num_substreams ) ) if ( FT_NEW_ARRAY( substreams, num_substreams ) )
@ -856,8 +885,8 @@
/* See https://www.w3.org/TR/WOFF2/#conform-mustRejectLoca */ /* See https://www.w3.org/TR/WOFF2/#conform-mustRejectLoca */
/* index_format = 0 => Short version `loca'. */ /* index_format = 0 => Short version `loca'. */
/* index_format = 1 => Long version `loca'. */ /* index_format = 1 => Long version `loca'. */
expected_loca_length = ( index_format ? 4 : 2 ) * expected_loca_length = ( index_format ? 4 : 2 ) *
( (FT_ULong)num_glyphs + 1 ); ( (FT_ULong)num_glyphs + 1 );
if ( loca_table->dst_length != expected_loca_length ) if ( loca_table->dst_length != expected_loca_length )
goto Fail; goto Fail;
@ -887,11 +916,11 @@
if ( FT_NEW_ARRAY( loca_values, num_glyphs + 1 ) ) if ( FT_NEW_ARRAY( loca_values, num_glyphs + 1 ) )
goto Fail; goto Fail;
points_size = 0; points_size = 0;
bbox_bitmap_offset = substreams[BBOX_STREAM].offset; bbox_bitmap_offset = substreams[BBOX_STREAM].offset;
/* Size of bboxBitmap = 4 * floor((numGlyphs + 31) / 32) */ /* Size of bboxBitmap = 4 * floor((numGlyphs + 31) / 32) */
bitmap_length = ( ( num_glyphs + 31 ) >> 5 ) << 2; bitmap_length = ( ( num_glyphs + 31 ) >> 5 ) << 2;
substreams[BBOX_STREAM].offset += bitmap_length; substreams[BBOX_STREAM].offset += bitmap_length;
glyph_buf_size = WOFF2_DEFAULT_GLYPH_BUF; glyph_buf_size = WOFF2_DEFAULT_GLYPH_BUF;
@ -919,7 +948,7 @@
if ( bbox_bitmap & ( 0x80 >> ( i & 7 ) ) ) if ( bbox_bitmap & ( 0x80 >> ( i & 7 ) ) )
have_bbox = TRUE; have_bbox = TRUE;
/* Read value from `nContourStream' */ /* Read value from `nContourStream'. */
if ( FT_STREAM_SEEK( substreams[N_CONTOUR_STREAM].offset ) || if ( FT_STREAM_SEEK( substreams[N_CONTOUR_STREAM].offset ) ||
FT_READ_USHORT( n_contours ) ) FT_READ_USHORT( n_contours ) )
goto Fail; goto Fail;
@ -927,7 +956,7 @@
if ( n_contours == 0xffff ) if ( n_contours == 0xffff )
{ {
/* Composite glyph */ /* composite glyph */
FT_Bool have_instructions = FALSE; FT_Bool have_instructions = FALSE;
FT_UShort instruction_size = 0; FT_UShort instruction_size = 0;
FT_ULong composite_size; FT_ULong composite_size;
@ -940,9 +969,9 @@
goto Fail; goto Fail;
if ( compositeGlyph_size( stream, if ( compositeGlyph_size( stream,
substreams[COMPOSITE_STREAM].offset, substreams[COMPOSITE_STREAM].offset,
&composite_size, &composite_size,
&have_instructions) ) &have_instructions) )
goto Fail; goto Fail;
if ( have_instructions ) if ( have_instructions )
@ -974,30 +1003,34 @@
if ( FT_STREAM_SEEK( substreams[BBOX_STREAM].offset ) || if ( FT_STREAM_SEEK( substreams[BBOX_STREAM].offset ) ||
FT_STREAM_READ( glyph_buf + glyph_size, 8 ) ) FT_STREAM_READ( glyph_buf + glyph_size, 8 ) )
goto Fail; goto Fail;
substreams[BBOX_STREAM].offset += 8; substreams[BBOX_STREAM].offset += 8;
glyph_size += 8; glyph_size += 8;
if ( FT_STREAM_SEEK( substreams[COMPOSITE_STREAM].offset ) || if ( FT_STREAM_SEEK( substreams[COMPOSITE_STREAM].offset ) ||
FT_STREAM_READ( glyph_buf + glyph_size, composite_size ) ) FT_STREAM_READ( glyph_buf + glyph_size, composite_size ) )
goto Fail; goto Fail;
substreams[COMPOSITE_STREAM].offset += composite_size; substreams[COMPOSITE_STREAM].offset += composite_size;
glyph_size += composite_size; glyph_size += composite_size;
if ( have_instructions ) if ( have_instructions )
{ {
pointer = glyph_buf + glyph_size; pointer = glyph_buf + glyph_size;
WRITE_USHORT( pointer, instruction_size ); WRITE_USHORT( pointer, instruction_size );
glyph_size += 2; glyph_size += 2;
if ( FT_STREAM_SEEK( substreams[INSTRUCTION_STREAM].offset ) || if ( FT_STREAM_SEEK( substreams[INSTRUCTION_STREAM].offset ) ||
FT_STREAM_READ( glyph_buf + glyph_size, instruction_size ) ) FT_STREAM_READ( glyph_buf + glyph_size, instruction_size ) )
goto Fail; goto Fail;
substreams[INSTRUCTION_STREAM].offset += instruction_size; substreams[INSTRUCTION_STREAM].offset += instruction_size;
glyph_size += instruction_size; glyph_size += instruction_size;
} }
} }
else if ( n_contours > 0 ) else if ( n_contours > 0 )
{ {
/* Simple glyph */ /* simple glyph */
FT_ULong total_n_points = 0; FT_ULong total_n_points = 0;
FT_UShort n_points_contour; FT_UShort n_points_contour;
FT_UInt j; FT_UInt j;
@ -1019,6 +1052,7 @@
if ( FT_STREAM_SEEK( substreams[N_POINTS_STREAM].offset ) ) if ( FT_STREAM_SEEK( substreams[N_POINTS_STREAM].offset ) )
goto Fail; goto Fail;
for ( j = 0; j < n_contours; ++j ) for ( j = 0; j < n_contours; ++j )
{ {
if ( READ_255USHORT( n_points_contour ) ) if ( READ_255USHORT( n_points_contour ) )
@ -1038,32 +1072,41 @@
flags_buf = stream->base + substreams[FLAG_STREAM].offset; flags_buf = stream->base + substreams[FLAG_STREAM].offset;
triplet_buf = stream->base + substreams[GLYPH_STREAM].offset; triplet_buf = stream->base + substreams[GLYPH_STREAM].offset;
triplet_size = substreams[GLYPH_STREAM].size - triplet_size = substreams[GLYPH_STREAM].size -
( substreams[GLYPH_STREAM].offset - ( substreams[GLYPH_STREAM].offset -
substreams[GLYPH_STREAM].start ); substreams[GLYPH_STREAM].start );
triplet_bytes_used = 0; triplet_bytes_used = 0;
/* Create array to store point information. */ /* Create array to store point information. */
points_size = total_n_points; points_size = total_n_points;
if ( FT_NEW_ARRAY( points, points_size ) ) if ( FT_NEW_ARRAY( points, points_size ) )
goto Fail; goto Fail;
if ( triplet_decode( flags_buf, triplet_buf, if ( triplet_decode( flags_buf,
triplet_size, total_n_points, triplet_buf,
points, &triplet_bytes_used ) ) triplet_size,
total_n_points,
points,
&triplet_bytes_used ) )
goto Fail; goto Fail;
substreams[FLAG_STREAM].offset += flag_size; substreams[FLAG_STREAM].offset += flag_size;
substreams[GLYPH_STREAM].offset += triplet_bytes_used; substreams[GLYPH_STREAM].offset += triplet_bytes_used;
if ( FT_STREAM_SEEK( substreams[GLYPH_STREAM].offset ) || if ( FT_STREAM_SEEK( substreams[GLYPH_STREAM].offset ) ||
READ_255USHORT( instruction_size ) ) READ_255USHORT( instruction_size ) )
goto Fail; goto Fail;
substreams[GLYPH_STREAM].offset = FT_STREAM_POS(); substreams[GLYPH_STREAM].offset = FT_STREAM_POS();
if ( total_n_points >= ( 1 << 27 ) || if ( total_n_points >= ( 1 << 27 ) ||
instruction_size >= ( 1 << 30 ) ) instruction_size >= ( 1 << 30 ) )
goto Fail; goto Fail;
size_needed = 12 + ( 2 * n_contours ) + ( 5 * total_n_points )
+ instruction_size; size_needed = 12 +
( 2 * n_contours ) +
( 5 * total_n_points ) +
instruction_size;
if ( glyph_buf_size < size_needed ) if ( glyph_buf_size < size_needed )
{ {
if ( FT_RENEW_ARRAY( glyph_buf, glyph_buf_size, size_needed ) ) if ( FT_RENEW_ARRAY( glyph_buf, glyph_buf_size, size_needed ) )
@ -1092,8 +1135,10 @@
compute_bbox( total_n_points, points, glyph_buf, &x_min ); compute_bbox( total_n_points, points, glyph_buf, &x_min );
glyph_size = CONTOUR_OFFSET_END_POINT; glyph_size = CONTOUR_OFFSET_END_POINT;
pointer = glyph_buf + glyph_size;
end_point = -1; pointer = glyph_buf + glyph_size;
end_point = -1;
for ( contour_ix = 0; contour_ix < n_contours; ++contour_ix ) for ( contour_ix = 0; contour_ix < n_contours; ++contour_ix )
{ {
end_point += n_points_arr[contour_ix]; end_point += n_points_arr[contour_ix];
@ -1106,15 +1151,21 @@
WRITE_USHORT( pointer, instruction_size ); WRITE_USHORT( pointer, instruction_size );
glyph_size += 2; glyph_size += 2;
if ( FT_STREAM_SEEK( substreams[INSTRUCTION_STREAM].offset ) || if ( FT_STREAM_SEEK( substreams[INSTRUCTION_STREAM].offset ) ||
FT_STREAM_READ( glyph_buf + glyph_size, instruction_size ) ) FT_STREAM_READ( glyph_buf + glyph_size, instruction_size ) )
goto Fail; goto Fail;
substreams[INSTRUCTION_STREAM].offset += instruction_size;
glyph_size += instruction_size;
if ( store_points( total_n_points, points, n_contours, substreams[INSTRUCTION_STREAM].offset += instruction_size;
instruction_size, glyph_buf, glyph_size += instruction_size;
glyph_buf_size, &glyph_size ) )
if ( store_points( total_n_points,
points,
n_contours,
instruction_size,
glyph_buf,
glyph_buf_size,
&glyph_size ) )
goto Fail; goto Fail;
FT_FREE( points ); FT_FREE( points );
@ -1122,7 +1173,7 @@
} }
else else
{ {
/* Empty glyph. */ /* Empty glyph. */
/* Must not have a bbox. */ /* Must not have a bbox. */
if ( have_bbox ) if ( have_bbox )
{ {
@ -1130,7 +1181,9 @@
goto Fail; goto Fail;
} }
} }
loca_values[i] = dest_offset - glyf_start; loca_values[i] = dest_offset - glyf_start;
if ( WRITE_SFNT_BUF( glyph_buf, glyph_size ) ) if ( WRITE_SFNT_BUF( glyph_buf, glyph_size ) )
goto Fail; goto Fail;
@ -1146,12 +1199,18 @@
glyf_table->dst_length = dest_offset - glyf_table->dst_offset; glyf_table->dst_length = dest_offset - glyf_table->dst_offset;
loca_table->dst_offset = dest_offset; loca_table->dst_offset = dest_offset;
/* loca[n] will be equal the length of the `glyf' table. */
/* `loca[n]' will be equal to the length of the `glyf' table. */
loca_values[num_glyphs] = glyf_table->dst_length; loca_values[num_glyphs] = glyf_table->dst_length;
if ( store_loca( loca_values, num_glyphs + 1, index_format, if ( store_loca( loca_values,
loca_checksum, &sfnt, sfnt_size, num_glyphs + 1,
&dest_offset, memory ) ) index_format,
loca_checksum,
&sfnt,
sfnt_size,
&dest_offset,
memory ) )
goto Fail; goto Fail;
loca_table->dst_length = dest_offset - loca_table->dst_offset; loca_table->dst_length = dest_offset - loca_table->dst_offset;
@ -1165,13 +1224,13 @@
*sfnt_bytes = sfnt; *sfnt_bytes = sfnt;
*out_offset = dest_offset; *out_offset = dest_offset;
FT_FREE( substreams ); FT_FREE( substreams );
FT_FREE( loca_values ); FT_FREE( loca_values );
FT_FREE( n_points_arr ); FT_FREE( n_points_arr );
FT_FREE( glyph_buf ); FT_FREE( glyph_buf );
FT_FREE( points ); FT_FREE( points );
return error; return error;
Fail: Fail:
if ( !error ) if ( !error )
@ -1187,7 +1246,7 @@
} }
/* Get `x_mins' for untransformed glyf table. */ /* Get `x_mins' for untransformed `glyf' table. */
static FT_Error static FT_Error
get_x_mins( FT_Stream stream, get_x_mins( FT_Stream stream,
WOFF2_Table* tables, WOFF2_Table* tables,
@ -1214,7 +1273,7 @@
TTAG_head ); TTAG_head );
/* Read `numGlyphs' from maxp table. */ /* Read `numGlyphs' field from `maxp' table. */
if ( FT_STREAM_SEEK( maxp_table->src_offset ) && FT_STREAM_SKIP( 8 ) ) if ( FT_STREAM_SEEK( maxp_table->src_offset ) && FT_STREAM_SKIP( 8 ) )
return error; return error;
@ -1223,7 +1282,7 @@
info->num_glyphs = num_glyphs; info->num_glyphs = num_glyphs;
/* Read `indexToLocFormat' from head table. */ /* Read `indexToLocFormat' field from `head' table. */
if ( FT_STREAM_SEEK( head_table->src_offset ) && FT_STREAM_SKIP( 50 ) ) if ( FT_STREAM_SEEK( head_table->src_offset ) && FT_STREAM_SKIP( 50 ) )
return error; return error;
@ -1232,7 +1291,7 @@
offset_size = index_format ? 4 : 2; offset_size = index_format ? 4 : 2;
/* Create x_mins array. */ /* Create `x_mins' array. */
if ( FT_NEW_ARRAY( info->x_mins, num_glyphs ) ) if ( FT_NEW_ARRAY( info->x_mins, num_glyphs ) )
return error; return error;
@ -1326,7 +1385,7 @@
FT_NEW_ARRAY( lsbs, num_glyphs ) ) FT_NEW_ARRAY( lsbs, num_glyphs ) )
goto Fail; goto Fail;
/* Read `advanceWidth' stream. Always present. */ /* Read `advanceWidth' stream. Always present. */
for ( i = 0; i < num_hmetrics; i++ ) for ( i = 0; i < num_hmetrics; i++ )
{ {
FT_UShort advance_width; FT_UShort advance_width;
@ -1335,7 +1394,7 @@
if ( FT_READ_USHORT( advance_width ) ) if ( FT_READ_USHORT( advance_width ) )
goto Fail; goto Fail;
advance_widths[i] = advance_width; advance_widths[i] = advance_width;
} }
/* lsb values for proportional glyphs. */ /* lsb values for proportional glyphs. */
@ -1355,7 +1414,7 @@
lsbs[i] = lsb; lsbs[i] = lsb;
} }
/* lsb values for monospaced glyphs */ /* lsb values for monospaced glyphs. */
for ( i = num_hmetrics; i < num_glyphs; i++ ) for ( i = num_hmetrics; i < num_glyphs; i++ )
{ {
FT_Short lsb; FT_Short lsb;
@ -1390,10 +1449,10 @@
WRITE_SHORT( dst, lsbs[i] ); WRITE_SHORT( dst, lsbs[i] );
FT_TRACE6(( "%d ", lsbs[i] )); FT_TRACE6(( "%d ", lsbs[i] ));
} }
FT_TRACE6(( "\n" )); FT_TRACE6(( "\n" ));
*checksum = compute_ULong_sum( hmtx_table, hmtx_table_size ); *checksum = compute_ULong_sum( hmtx_table, hmtx_table_size );
/* Write hmtx table to sfnt buffer. */ /* Write `hmtx' table to sfnt buffer. */
if ( WRITE_SFNT_BUF( hmtx_table, hmtx_table_size ) ) if ( WRITE_SFNT_BUF( hmtx_table, hmtx_table_size ) )
goto Fail; goto Fail;
@ -1421,13 +1480,13 @@
FT_ULong* sfnt_size, FT_ULong* sfnt_size,
FT_Memory memory ) FT_Memory memory )
{ {
FT_Error error = FT_Err_Ok; FT_Error error = FT_Err_Ok;
FT_Stream stream = NULL; FT_Stream stream = NULL;
FT_Byte* buf_cursor = NULL; FT_Byte* buf_cursor = NULL;
FT_Byte* table_entry = NULL; FT_Byte* table_entry = NULL;
/* We are reallocating memory for `sfnt', so its pointer may change. */ /* We are reallocating memory for `sfnt', so its pointer may change. */
FT_Byte* sfnt = *sfnt_bytes; FT_Byte* sfnt = *sfnt_bytes;
FT_UShort num_tables = woff2->num_tables; FT_UShort num_tables = woff2->num_tables;
FT_ULong dest_offset = 12 + num_tables * 16UL; FT_ULong dest_offset = 12 + num_tables * 16UL;
@ -1442,8 +1501,8 @@
FT_ULong table_entry_offset = 12; FT_ULong table_entry_offset = 12;
WOFF2_Table head_table; WOFF2_Table head_table;
/* Few table checks before reconstruction. */ /* A few table checks before reconstruction. */
/* `glyf' must be present with `loca'. */ /* `glyf' must be present with `loca'. */
const WOFF2_Table glyf_table = find_table( indices, num_tables, const WOFF2_Table glyf_table = find_table( indices, num_tables,
TTAG_glyf ); TTAG_glyf );
const WOFF2_Table loca_table = find_table( indices, num_tables, const WOFF2_Table loca_table = find_table( indices, num_tables,
@ -1453,7 +1512,7 @@
if ( ( !glyf_table && loca_table ) || if ( ( !glyf_table && loca_table ) ||
( !loca_table && glyf_table ) ) ( !loca_table && glyf_table ) )
{ {
FT_ERROR(( "Cannot have only one of glyf/loca.\n" )); FT_ERROR(( "Both `glyph' and `loca' tables must be present.\n" ));
return FT_THROW( Invalid_Table ); return FT_THROW( Invalid_Table );
} }
@ -1462,10 +1521,11 @@
{ {
if ( ( glyf_table->flags & WOFF2_FLAGS_TRANSFORM ) != if ( ( glyf_table->flags & WOFF2_FLAGS_TRANSFORM ) !=
( loca_table->flags & WOFF2_FLAGS_TRANSFORM ) ) ( loca_table->flags & WOFF2_FLAGS_TRANSFORM ) )
{ {
FT_ERROR(( "Transformation mismatch in glyf and loca." )); FT_ERROR(( "Transformation mismatch"
return FT_THROW( Invalid_Table ); " between `glyf' and `loca' table." ));
} return FT_THROW( Invalid_Table );
}
} }
/* Create buffer for table entries. */ /* Create buffer for table entries. */
@ -1490,10 +1550,10 @@
FT_TRACE3(( "Seeking to %d with table size %d.\n", FT_TRACE3(( "Seeking to %d with table size %d.\n",
table.src_offset, table.src_length )); table.src_offset, table.src_length ));
FT_TRACE3(( "Table tag: %c%c%c%c.\n", FT_TRACE3(( "Table tag: %c%c%c%c.\n",
(FT_Char)( table.Tag >> 24 ), (FT_Char)( table.Tag >> 24 ),
(FT_Char)( table.Tag >> 16 ), (FT_Char)( table.Tag >> 16 ),
(FT_Char)( table.Tag >> 8 ), (FT_Char)( table.Tag >> 8 ),
(FT_Char)( table.Tag ) )); (FT_Char)( table.Tag ) ));
if ( FT_STREAM_SEEK( table.src_offset ) ) if ( FT_STREAM_SEEK( table.src_offset ) )
return FT_THROW( Invalid_Table ); return FT_THROW( Invalid_Table );
@ -1523,17 +1583,19 @@
/* Set checkSumAdjustment = 0 */ /* Set checkSumAdjustment = 0 */
WRITE_ULONG( buf_cursor, 0 ); WRITE_ULONG( buf_cursor, 0 );
} }
table.dst_offset = dest_offset;
checksum = compute_ULong_sum( transformed_buf + table.src_offset,
table.src_length );
table.dst_offset = dest_offset;
checksum = compute_ULong_sum( transformed_buf + table.src_offset,
table.src_length );
FT_TRACE4(( "Checksum = %09x.\n", checksum )); FT_TRACE4(( "Checksum = %09x.\n", checksum ));
if ( WRITE_SFNT_BUF( transformed_buf + table.src_offset, if ( WRITE_SFNT_BUF( transformed_buf + table.src_offset,
table.src_length ) ) table.src_length ) )
return FT_THROW( Invalid_Table ); return FT_THROW( Invalid_Table );
} }
else{ else
{
FT_TRACE3(( "This table is transformed.\n" )); FT_TRACE3(( "This table is transformed.\n" ));
if ( table.Tag == TTAG_glyf ) if ( table.Tag == TTAG_glyf )
@ -1541,42 +1603,57 @@
is_glyf_xform = TRUE; is_glyf_xform = TRUE;
table.dst_offset = dest_offset; table.dst_offset = dest_offset;
if ( reconstruct_glyf( stream, &table, &checksum, if ( reconstruct_glyf( stream,
loca_table, &loca_checksum, &table,
&sfnt, sfnt_size, &dest_offset, &checksum,
info, memory ) ) loca_table,
&loca_checksum,
&sfnt,
sfnt_size,
&dest_offset,
info,
memory ) )
return FT_THROW( Invalid_Table ); return FT_THROW( Invalid_Table );
FT_TRACE4(("Checksum = %09x.\n", checksum));
FT_TRACE4(( "Checksum = %09x.\n", checksum ));
} }
else if ( table.Tag == TTAG_loca ) else if ( table.Tag == TTAG_loca )
{
checksum = loca_checksum; checksum = loca_checksum;
}
else if ( table.Tag == TTAG_hmtx ) else if ( table.Tag == TTAG_hmtx )
{ {
/* If glyf is not transformed and hmtx is, handle separately. */ /* If glyf is not transformed and hmtx is, handle separately. */
if ( !is_glyf_xform ) if ( !is_glyf_xform )
{ {
if ( get_x_mins(stream, indices, num_tables, info, memory) ) if ( get_x_mins( stream, indices, num_tables, info, memory ) )
return FT_THROW( Invalid_Table ); return FT_THROW( Invalid_Table );
} }
table.dst_offset = dest_offset; table.dst_offset = dest_offset;
if ( reconstruct_hmtx( stream, table.src_length,
info->num_glyphs, info->num_hmetrics, if ( reconstruct_hmtx( stream,
info->x_mins, &checksum, table.src_length,
&sfnt, sfnt_size, info->num_glyphs,
&dest_offset, memory ) ) info->num_hmetrics,
info->x_mins,
&checksum,
&sfnt,
sfnt_size,
&dest_offset,
memory ) )
return FT_THROW( Invalid_Table ); return FT_THROW( Invalid_Table );
} }
else else
{ {
/* Unknown transform */ /* Unknown transform. */
FT_ERROR(( "Unknown table transform.\n" )); FT_ERROR(( "Unknown table transform.\n" ));
return FT_THROW( Invalid_Table ); return FT_THROW( Invalid_Table );
} }
} }
font_checksum += checksum; font_checksum += checksum;
buf_cursor = &table_entry[0]; buf_cursor = &table_entry[0];
WRITE_ULONG( buf_cursor, table.Tag ); WRITE_ULONG( buf_cursor, table.Tag );
WRITE_ULONG( buf_cursor, checksum ); WRITE_ULONG( buf_cursor, checksum );
@ -1606,8 +1683,10 @@
if ( head_table->dst_length < 12 ) if ( head_table->dst_length < 12 )
goto Fail; goto Fail;
} }
buf_cursor = sfnt + head_table->dst_offset + 8;
buf_cursor = sfnt + head_table->dst_offset + 8;
font_checksum = 0xB1B0AFBA - font_checksum; font_checksum = 0xB1B0AFBA - font_checksum;
WRITE_ULONG( buf_cursor, font_checksum ); WRITE_ULONG( buf_cursor, font_checksum );
FT_TRACE2(( "Final checksum = %09x.\n", font_checksum )); FT_TRACE2(( "Final checksum = %09x.\n", font_checksum ));
@ -1644,9 +1723,9 @@
FT_Int* face_instance_index, FT_Int* face_instance_index,
FT_Long* num_faces ) FT_Long* num_faces )
{ {
FT_Memory memory = stream->memory; FT_Memory memory = stream->memory;
FT_Error error = FT_Err_Ok; FT_Error error = FT_Err_Ok;
FT_Int face_index; FT_Int face_index;
WOFF2_HeaderRec woff2; WOFF2_HeaderRec woff2;
WOFF2_InfoRec info; WOFF2_InfoRec info;
@ -1655,22 +1734,22 @@
WOFF2_Table* temp_indices = NULL; WOFF2_Table* temp_indices = NULL;
WOFF2_Table last_table; WOFF2_Table last_table;
FT_Int nn; FT_Int nn;
FT_ULong j; FT_ULong j;
FT_ULong flags; FT_ULong flags;
FT_UShort xform_version; FT_UShort xform_version;
FT_ULong src_offset = 0; FT_ULong src_offset = 0;
FT_UInt glyf_index; FT_UInt glyf_index;
FT_UInt loca_index; FT_UInt loca_index;
FT_UInt64 file_offset; FT_UInt64 file_offset;
FT_Byte* sfnt = NULL; FT_Byte* sfnt = NULL;
FT_Stream sfnt_stream = NULL; FT_Stream sfnt_stream = NULL;
FT_Byte* sfnt_header; FT_Byte* sfnt_header;
FT_ULong sfnt_size; FT_ULong sfnt_size;
FT_Byte* uncompressed_buf = NULL; FT_Byte* uncompressed_buf = NULL;
static const FT_Frame_Field woff2_header_fields[] = static const FT_Frame_Field woff2_header_fields[] =
{ {
@ -1793,6 +1872,7 @@
{ {
if ( READ_BASE128( table->TransformLength ) ) if ( READ_BASE128( table->TransformLength ) )
goto Exit; goto Exit;
if ( table->Tag == TTAG_loca && table->TransformLength ) if ( table->Tag == TTAG_loca && table->TransformLength )
{ {
FT_ERROR(( "woff2_open_font: Invalid loca `transformLength'.\n" )); FT_ERROR(( "woff2_open_font: Invalid loca `transformLength'.\n" ));
@ -1810,8 +1890,8 @@
table->src_offset = src_offset; table->src_offset = src_offset;
table->src_length = table->TransformLength; table->src_length = table->TransformLength;
src_offset += table->TransformLength; src_offset += table->TransformLength;
table->flags = flags; table->flags = flags;
FT_TRACE2(( " %c%c%c%c %08d %08d %08ld %08ld\n", FT_TRACE2(( " %c%c%c%c %08d %08d %08ld %08ld\n",
(FT_Char)( table->Tag >> 24 ), (FT_Char)( table->Tag >> 24 ),
@ -1830,8 +1910,9 @@
/* End of last table is uncompressed size. */ /* End of last table is uncompressed size. */
last_table = indices[woff2.num_tables - 1]; last_table = indices[woff2.num_tables - 1];
woff2.uncompressed_size = last_table->src_offset
+ last_table->src_length; woff2.uncompressed_size = last_table->src_offset +
last_table->src_length;
if ( woff2.uncompressed_size < last_table->src_offset ) if ( woff2.uncompressed_size < last_table->src_offset )
{ {
error = FT_THROW( Invalid_Table ); error = FT_THROW( Invalid_Table );
@ -1843,8 +1924,11 @@
/* Check for and read collection directory. */ /* Check for and read collection directory. */
woff2.num_fonts = 1; woff2.num_fonts = 1;
woff2.header_version = 0; woff2.header_version = 0;
if ( woff2.flavor == TTAG_ttcf ){
if ( woff2.flavor == TTAG_ttcf )
{
FT_TRACE2(( "Font is a TTC, reading collection directory.\n" )); FT_TRACE2(( "Font is a TTC, reading collection directory.\n" ));
if ( FT_READ_ULONG( woff2.header_version ) ) if ( FT_READ_ULONG( woff2.header_version ) )
goto Exit; goto Exit;
@ -1893,7 +1977,7 @@
if ( READ_255USHORT( table_index ) ) if ( READ_255USHORT( table_index ) )
goto Exit; goto Exit;
FT_TRACE6(("%hu ", table_index)); FT_TRACE6(( "%hu ", table_index ));
ttc_font->table_indices[j] = table_index; ttc_font->table_indices[j] = table_index;
table = indices[table_index]; table = indices[table_index];
@ -1916,15 +2000,16 @@
} }
} }
} }
/* Collection directory reading complete. */ /* Collection directory reading complete. */
FT_TRACE2(( "WOFF2 collection dirtectory is valid.\n" )); FT_TRACE2(( "WOFF2 collection dirtectory is valid.\n" ));
} }
woff2.compressed_offset = FT_STREAM_POS(); woff2.compressed_offset = FT_STREAM_POS();
file_offset = ROUND4( woff2.compressed_offset + file_offset = ROUND4( woff2.compressed_offset +
woff2.totalCompressedSize ); woff2.totalCompressedSize );
/* Few more checks before we start reading the tables. */ /* Some more checks before we start reading the tables. */
if ( file_offset > woff2.length ) if ( file_offset > woff2.length )
{ {
error = FT_THROW( Invalid_Table ); error = FT_THROW( Invalid_Table );
@ -1997,6 +2082,7 @@
for ( nn = 0; nn < ttc_font->num_tables; nn++ ) for ( nn = 0; nn < ttc_font->num_tables; nn++ )
indices[nn] = temp_indices[nn]; indices[nn] = temp_indices[nn];
FT_FREE( temp_indices ); FT_FREE( temp_indices );
/* Change header values. */ /* Change header values. */
@ -2061,15 +2147,22 @@
goto Exit; goto Exit;
/* Uncompress the stream. */ /* Uncompress the stream. */
error = woff2_decompress( uncompressed_buf, woff2.uncompressed_size, error = woff2_decompress( uncompressed_buf,
stream->cursor, woff2.totalCompressedSize ); woff2.uncompressed_size,
stream->cursor,
woff2.totalCompressedSize );
if ( error ) if ( error )
goto Exit; goto Exit;
FT_FRAME_EXIT(); FT_FRAME_EXIT();
error = reconstruct_font( uncompressed_buf, woff2.uncompressed_size, error = reconstruct_font( uncompressed_buf,
indices, &woff2, &info, &sfnt, &sfnt_size, woff2.uncompressed_size,
indices,
&woff2,
&info,
&sfnt,
&sfnt_size,
memory ); memory );
if ( error ) if ( error )
goto Exit; goto Exit;
@ -2085,8 +2178,8 @@
goto Exit; goto Exit;
} }
/* reconstruct_font has done all the work. */ /* `reconstruct_font' has done all the work. */
/* Swap out stream and return. */ /* Swap out stream and return. */
FT_Stream_OpenMemory( sfnt_stream, sfnt, woff2.actual_sfnt_size ); FT_Stream_OpenMemory( sfnt_stream, sfnt, woff2.actual_sfnt_size );
sfnt_stream->memory = stream->memory; sfnt_stream->memory = stream->memory;
sfnt_stream->close = stream_close; sfnt_stream->close = stream_close;
@ -2095,8 +2188,7 @@
face->root.stream, face->root.stream,
( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 ); ( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
face->root.stream = sfnt_stream; face->root.stream = sfnt_stream;
face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
/* Set face_index to 0 or -1. */ /* Set face_index to 0 or -1. */

View File

@ -28,20 +28,20 @@
FT_BEGIN_HEADER FT_BEGIN_HEADER
/* Leave the first byte open to store flag_byte. */ /* Leave the first byte open to store `flag_byte'. */
#define WOFF2_FLAGS_TRANSFORM 1 << 8 #define WOFF2_FLAGS_TRANSFORM 1 << 8
#define WOFF2_SFNT_HEADER_SIZE 12 #define WOFF2_SFNT_HEADER_SIZE 12
#define WOFF2_SFNT_ENTRY_SIZE 16 #define WOFF2_SFNT_ENTRY_SIZE 16
/* Suggested max size for output. */ /* Suggested maximum size for output. */
#define WOFF2_DEFAULT_MAX_SIZE 30 * 1024 * 1024 #define WOFF2_DEFAULT_MAX_SIZE 30 * 1024 * 1024
/* 98% of Google Fonts have no glyph above 5k bytes. */ /* 98% of Google Fonts have no glyph above 5k bytes. */
#define WOFF2_DEFAULT_GLYPH_BUF 5120 #define WOFF2_DEFAULT_GLYPH_BUF 5120
/* Composite glyph flags */ /* Composite glyph flags. */
/* See CompositeGlyph.java in `sfntly' for full definitions */ /* See `CompositeGlyph.java' in `sfntly' for full definitions. */
#define FLAG_ARG_1_AND_2_ARE_WORDS 1 << 0 #define FLAG_ARG_1_AND_2_ARE_WORDS 1 << 0
#define FLAG_WE_HAVE_A_SCALE 1 << 3 #define FLAG_WE_HAVE_A_SCALE 1 << 3
#define FLAG_MORE_COMPONENTS 1 << 5 #define FLAG_MORE_COMPONENTS 1 << 5

View File

@ -15,11 +15,21 @@
* *
*/ */
#include <ft2build.h> #include <ft2build.h>
#include "sfwoff.h" #include "sfwoff.h"
#include FT_TRUETYPE_TAGS_H #include FT_TRUETYPE_TAGS_H
/* Return tag from index in the order given in WOFF2 specification. */
/*
* Return tag from index in the order given in WOFF2 specification.
*
* See
*
* https://www.w3.org/TR/WOFF2/#table_dir_format
*
* for details.
*/
FT_LOCAL_DEF( FT_ULong ) FT_LOCAL_DEF( FT_ULong )
woff2_known_tags( FT_Byte index ) woff2_known_tags( FT_Byte index )
{ {