summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikhil Ramakrishnan <ramakrishnan.nikhil@gmail.com>2019-06-12 00:21:20 +0530
committerNikhil Ramakrishnan <ramakrishnan.nikhil@gmail.com>2019-06-16 19:09:07 +0530
commit1b7f95bf708b622334521a210f145ddcc7aa5349 (patch)
treec8e8bc56a531f4a7adc60598098c7a3bbd0f4d85
parentc26c91aa39dcbc383e9db1cdee1191d8073db148 (diff)
downloadfreetype2-1b7f95bf708b622334521a210f145ddcc7aa5349.tar.gz
Read WOFF 2 header.
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.
-rw-r--r--include/freetype/internal/fttrace.h1
-rw-r--r--src/sfnt/rules.mk1
-rw-r--r--src/sfnt/sfnt.c1
-rw-r--r--src/sfnt/sfobjs.c17
-rw-r--r--src/sfnt/sfwoff2.c169
-rw-r--r--src/sfnt/sfwoff2.h41
6 files changed, 230 insertions, 0 deletions
diff --git a/include/freetype/internal/fttrace.h b/include/freetype/internal/fttrace.h
index f5f959804..77e0e4190 100644
--- a/include/freetype/internal/fttrace.h
+++ b/include/freetype/internal/fttrace.h
@@ -49,6 +49,7 @@ FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */
FT_TRACE_DEF( sfdriver ) /* SFNT font driver (sfdriver.c) */
FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */
FT_TRACE_DEF( sfwoff ) /* WOFF format handler (sfwoff.c) */
+FT_TRACE_DEF( sfwoff2 ) /* WOFF2 format handler (sfwoff2.c) */
FT_TRACE_DEF( ttbdf ) /* TrueType embedded BDF (ttbdf.c) */
FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */
FT_TRACE_DEF( ttcolr ) /* glyph layer table (ttcolr.c) */
diff --git a/src/sfnt/rules.mk b/src/sfnt/rules.mk
index ee3314eac..a77b8ddd1 100644
--- a/src/sfnt/rules.mk
+++ b/src/sfnt/rules.mk
@@ -32,6 +32,7 @@ SFNT_DRV_SRC := $(SFNT_DIR)/pngshim.c \
$(SFNT_DIR)/sfdriver.c \
$(SFNT_DIR)/sfobjs.c \
$(SFNT_DIR)/sfwoff.c \
+ $(SFNT_DIR)/sfwoff2.c \
$(SFNT_DIR)/ttbdf.c \
$(SFNT_DIR)/ttcmap.c \
$(SFNT_DIR)/ttcolr.c \
diff --git a/src/sfnt/sfnt.c b/src/sfnt/sfnt.c
index b4faf34a3..9fed618a6 100644
--- a/src/sfnt/sfnt.c
+++ b/src/sfnt/sfnt.c
@@ -23,6 +23,7 @@
#include "sfdriver.c"
#include "sfobjs.c"
#include "sfwoff.c"
+#include "sfwoff2.c"
#include "ttbdf.c"
#include "ttcmap.c"
#include "ttcolr.c"
diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c
index 6edf3ae1d..b5a6523cf 100644
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -22,6 +22,7 @@
#include "ttcmap.h"
#include "ttkern.h"
#include "sfwoff.h"
+#include "sfwoff2.h"
#include FT_INTERNAL_SFNT_H
#include FT_INTERNAL_DEBUG_H
#include FT_TRUETYPE_IDS_H
@@ -385,6 +386,22 @@
goto retry;
}
+ if ( tag == TTAG_wOF2 )
+ {
+ FT_TRACE2(( "sfnt_open_font: file is a WOFF2; synthesizing SFNT\n" ));
+
+ if ( FT_STREAM_SEEK( offset ) )
+ return error;
+
+ error = woff2_open_font( stream, face );
+ if ( error )
+ return error;
+
+ /* Swap out stream and retry! */
+ stream = face->root.stream;
+ goto retry;
+ }
+
if ( tag != 0x00010000UL &&
tag != TTAG_ttcf &&
tag != TTAG_OTTO &&
diff --git a/src/sfnt/sfwoff2.c b/src/sfnt/sfwoff2.c
new file mode 100644
index 000000000..e205b6679
--- /dev/null
+++ b/src/sfnt/sfwoff2.c
@@ -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 */
diff --git a/src/sfnt/sfwoff2.h b/src/sfnt/sfwoff2.h
new file mode 100644
index 000000000..5c3cc3d72
--- /dev/null
+++ b/src/sfnt/sfwoff2.h
@@ -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 */