freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] GSoC-2019-Nikhil 1b7f95b 2/5: Read WOFF 2 header.


From: Nikhil Ramakrishnan
Subject: [freetype2] GSoC-2019-Nikhil 1b7f95b 2/5: Read WOFF 2 header.
Date: Sun, 16 Jun 2019 09:51:48 -0400 (EDT)

branch: GSoC-2019-Nikhil
commit 1b7f95bf708b622334521a210f145ddcc7aa5349
Author: Nikhil Ramakrishnan <address@hidden>
Commit: Nikhil Ramakrishnan <address@hidden>

    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.
---
 include/freetype/internal/fttrace.h |   1 +
 src/sfnt/rules.mk                   |   1 +
 src/sfnt/sfnt.c                     |   1 +
 src/sfnt/sfobjs.c                   |  17 ++++
 src/sfnt/sfwoff2.c                  | 169 ++++++++++++++++++++++++++++++++++++
 src/sfnt/{sfnt.c => sfwoff2.h}      |  41 +++++----
 6 files changed, 211 insertions(+), 19 deletions(-)

diff --git a/include/freetype/internal/fttrace.h 
b/include/freetype/internal/fttrace.h
index f5f9598..77e0e41 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 ee3314e..a77b8dd 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 b4faf34..9fed618 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 6edf3ae..b5a6523 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 0000000..e205b66
--- /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/sfnt.c b/src/sfnt/sfwoff2.h
similarity index 50%
copy from src/sfnt/sfnt.c
copy to src/sfnt/sfwoff2.h
index b4faf34..5c3cc3d 100644
--- a/src/sfnt/sfnt.c
+++ b/src/sfnt/sfwoff2.h
@@ -1,11 +1,11 @@
 /****************************************************************************
  *
- * sfnt.c
+ * sfwoff2.h
  *
- *   Single object library component.
+ *   WOFFF2 format management (specification).
  *
- * Copyright (C) 1996-2019 by
- * David Turner, Robert Wilhelm, and Werner Lemberg.
+ * 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
@@ -16,23 +16,26 @@
  */
 
 
-#define FT_MAKE_OPTION_SINGLE_OBJECT
+#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
 
-#include "pngshim.c"
-#include "sfdriver.c"
-#include "sfobjs.c"
-#include "sfwoff.c"
-#include "ttbdf.c"
-#include "ttcmap.c"
-#include "ttcolr.c"
-#include "ttcpal.c"
-
-#include "ttkern.c"
-#include "ttload.c"
-#include "ttmtx.c"
-#include "ttpost.c"
-#include "ttsbit.c"
+#endif /* SFWOFF2_H_ */
 
 
 /* END */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]