Check for WOFF2 tag, call `woff2_open_font', and implement it to read header according to specification. * include/freetype/internal/fttrace.h: Add `sfwoff2.c'. * src/sfnt/rules.mk: Add `sfwoff2.c'. * src/sfnt/sfnt.c: Include `sfwoff2.c'. * src/sfnt/sfobjs.c: Check for `wOF2' tag and call `woff2_open_font'. * src/sfnt/sfwoff2.c, src/sfnt/sfwoff2.h: New files.GSoC-2019-nikhil
parent
c26c91aa39
commit
1b7f95bf70
6 changed files with 230 additions and 0 deletions
@ -0,0 +1,169 @@ |
||||
/****************************************************************************
|
||||
* |
||||
* sfwoff2.c |
||||
* |
||||
* WOFF2 format management (base). |
||||
* |
||||
* Copyright (C) 2019 by |
||||
* Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg. |
||||
* |
||||
* 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 "sfwoff2.h" |
||||
#include FT_TRUETYPE_TAGS_H |
||||
#include FT_INTERNAL_DEBUG_H |
||||
#include FT_INTERNAL_STREAM_H |
||||
|
||||
|
||||
/**************************************************************************
|
||||
* |
||||
* The macro FT_COMPONENT is used in trace mode. It is an implicit |
||||
* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log |
||||
* messages during execution. |
||||
*/ |
||||
#undef FT_COMPONENT |
||||
#define FT_COMPONENT sfwoff2 |
||||
|
||||
|
||||
static FT_Error |
||||
ReadBase128( FT_Stream stream, |
||||
FT_ULong* value ) |
||||
{ |
||||
FT_ULong result = 0; |
||||
FT_Int i; |
||||
FT_Byte code; |
||||
FT_Byte* p = stream->cursor; |
||||
|
||||
for ( i = 0; i < 5; ++i ) { |
||||
code = 0; |
||||
code = FT_NEXT_BYTE( p ); |
||||
|
||||
/* Leading zeros are invalid. */ |
||||
if ( i == 0 && code == 0x80 ) { |
||||
return FT_THROW( Invalid_Table ); |
||||
} |
||||
|
||||
/* If any of top seven bits are set then we're about to overflow. */ |
||||
if ( result & 0xfe000000 ){ |
||||
return FT_THROW( Invalid_Table ); |
||||
} |
||||
|
||||
result = ( result << 7 ) | ( code & 0x7f ); |
||||
|
||||
/* Spin until most significant bit of data byte is false. */ |
||||
if ( (code & 0x80) == 0 ) { |
||||
*value = result; |
||||
return FT_Err_Ok; |
||||
} |
||||
} |
||||
/* Make sure not to exceed the size bound. */ |
||||
return FT_THROW( Invalid_Table ); |
||||
} |
||||
|
||||
|
||||
/* 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 ) |
||||
{ |
||||
FT_Memory memory = stream->memory; |
||||
FT_Error error = FT_Err_Ok; |
||||
FT_Byte* p = stream->cursor; |
||||
FT_Byte* limit = stream->limit; |
||||
|
||||
WOFF2_HeaderRec woff2; |
||||
WOFF2_Table tables = NULL; |
||||
WOFF2_Table* indices = NULL; |
||||
|
||||
static const FT_Frame_Field woff2_header_fields[] = |
||||
{ |
||||
#undef FT_STRUCTURE |
||||
#define FT_STRUCTURE WOFF2_HeaderRec |
||||
|
||||
FT_FRAME_START( 48 ), |
||||
FT_FRAME_ULONG ( signature ), |
||||
FT_FRAME_ULONG ( flavor ), |
||||
FT_FRAME_ULONG ( length ), |
||||
FT_FRAME_USHORT( num_tables ), |
||||
FT_FRAME_SKIP_BYTES( 2 + 4 ), |
||||
FT_FRAME_ULONG ( totalCompressedSize ), |
||||
FT_FRAME_SKIP_BYTES( 2 * 2 ), |
||||
FT_FRAME_ULONG ( metaOffset ), |
||||
FT_FRAME_ULONG ( metaLength ), |
||||
FT_FRAME_ULONG ( metaOrigLength ), |
||||
FT_FRAME_ULONG ( privOffset ), |
||||
FT_FRAME_ULONG ( privLength ), |
||||
FT_FRAME_END |
||||
}; |
||||
|
||||
FT_UNUSED( p ); |
||||
FT_UNUSED( limit ); |
||||
FT_UNUSED( tables ); |
||||
FT_UNUSED( indices ); |
||||
FT_UNUSED( memory ); |
||||
|
||||
/* DEBUG - Remove later */ |
||||
FT_TRACE2(("woff2_open_font: Received Data.\n")); |
||||
|
||||
FT_ASSERT( stream == face->root.stream ); |
||||
FT_ASSERT( FT_STREAM_POS() == 0 ); |
||||
|
||||
/* Read WOFF2 Header. */ |
||||
if ( FT_STREAM_READ_FIELDS( woff2_header_fields, &woff2 ) ) |
||||
return error; |
||||
|
||||
/* DEBUG - Remove later. */ |
||||
FT_TRACE2(("signature -> 0x%X\n", woff2.signature)); |
||||
FT_TRACE2(("flavor -> 0x%X\n", woff2.flavor)); |
||||
FT_TRACE2(("length -> %lu\n", woff2.length)); |
||||
FT_TRACE2(("num_tables -> %hu\n", woff2.num_tables)); |
||||
FT_TRACE2(("metaOffset -> %hu\n", woff2.metaOffset)); |
||||
FT_TRACE2(("metaLength -> %hu\n", woff2.metaLength)); |
||||
FT_TRACE2(("privOffset -> %hu\n", woff2.privOffset)); |
||||
FT_TRACE2(("privLength -> %hu\n", woff2.privLength)); |
||||
|
||||
/* Make sure we don't recurse back here. */ |
||||
if ( woff2.flavor == TTAG_wOF2 ) |
||||
return FT_THROW( Invalid_Table ); |
||||
|
||||
/* Miscellaneous checks. */ |
||||
if ( woff2.length != stream->size || |
||||
woff2.num_tables == 0 || |
||||
48 + woff2.num_tables * 20UL >= woff2.length || |
||||
( woff2.metaOffset == 0 && ( woff2.metaLength != 0 || |
||||
woff2.metaOrigLength != 0 ) ) || |
||||
( woff2.metaLength != 0 && woff2.metaOrigLength == 0 ) || |
||||
( woff2.metaOffset >= woff2.length ) || |
||||
( woff2.length - woff2.metaOffset < woff2.metaLength ) || |
||||
( woff2.privOffset == 0 && woff2.privLength != 0 ) || |
||||
( woff2.privOffset >= woff2.length ) || |
||||
( woff2.length - woff2.privOffset < woff2.privLength ) ) |
||||
{ |
||||
FT_ERROR(( "woff_font_open: invalid WOFF2 header\n" )); |
||||
return FT_THROW( Invalid_Table ); |
||||
} |
||||
/* DEBUG - Remove later. */ |
||||
else{ |
||||
FT_TRACE2(("WOFF2 Header is valid.\n")); |
||||
} |
||||
|
||||
/* TODO Read table directory. */ |
||||
|
||||
error = FT_THROW( Unimplemented_Feature ); |
||||
goto Exit; |
||||
|
||||
Exit: |
||||
return error; |
||||
} |
||||
|
||||
|
||||
/* END */ |
@ -0,0 +1,41 @@ |
||||
/****************************************************************************
|
||||
* |
||||
* sfwoff2.h |
||||
* |
||||
* WOFFF2 format management (specification). |
||||
* |
||||
* Copyright (C) 2019 by |
||||
* Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg. |
||||
* |
||||
* 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. |
||||
* |
||||
*/ |
||||
|
||||
|
||||
#ifndef SFWOFF2_H_ |
||||
#define SFWOFF2_H_ |
||||
|
||||
|
||||
#include <ft2build.h> |
||||
#include FT_INTERNAL_SFNT_H |
||||
#include FT_INTERNAL_OBJECTS_H |
||||
|
||||
|
||||
FT_BEGIN_HEADER |
||||
|
||||
|
||||
FT_LOCAL( FT_Error ) |
||||
woff2_open_font( FT_Stream stream, |
||||
TT_Face face ); |
||||
|
||||
|
||||
FT_END_HEADER |
||||
|
||||
#endif /* SFWOFF2_H_ */ |
||||
|
||||
|
||||
/* END */ |
Loading…
Reference in new issue