Compare commits

...

25 Commits

Author SHA1 Message Date
Nikhil Ramakrishnan f67786de4d [woff2] Check whether known tag is in array bounds.
If table tag is not 0x3f, we expect a value between 0 and 62. If this is
not the case, exit with errors.

* src/sfnt/sfwoff2/c: Check whether table tag makes sense.

* src/sfnt/woff2tags.c: Return 0 if tag is out of bounds.
2019-08-22 16:46:03 +05:30
Nikhil Ramakrishnan 933c185b7e [woff2] More formatting and documentation.
* include/freetype/internal/wofftypes.h, src/sfnt/sfwoff2.c: Implement
formatting changes suggested as

  https://lists.nongnu.org/archive/html/freetype-devel/2019-08/msg00052.html
2019-08-21 20:21:02 +05:30
Nikhil Ramakrishnan 25774f3da5 * src/sfnt/sfwoff2.c: Improve trace comments.
Add tracing levels for comments, and more formatting.
2019-08-17 14:57:59 +05:30
Nikhil Ramakrishnan 3f35a033b6 [woff2] Formatting.
* src/sfnt/sfobjs.c, src/sfnt/sfwoff2.c: Better formatting.
2019-08-14 17:39:55 +05:30
Nikhil Ramakrishnan 73dc5ef018 [woff2] Support hmtx reconstruction when glyf is untransformed.
`reconstruct_hmtx' requires `info->x_mins' and `info->num_glyphs' to
reconstruct the hmtx table. In case glyf is not transformed, we call
`get_x_mins' which does the necessary work.

(get_x_mins): New function.
(reconstruct_font): Call get_x_mins.
2019-08-14 02:36:27 +05:30
Nikhil Ramakrishnan b25c352ed4 [sfnt] Support `face->num_faces' for WOFF2 fonts.
Set correct value of `face->num_faces' for WOFF2 fonts. This is being
handled separately because we only load the tables for the requested
font face in `woff2_open_font' and create a single-face sfnt stream.

The full discussion is at:

  https://lists.gnu.org/archive/html/freetype-devel/2019-08/msg00000.html

* src/sfnt/sfobjs.c (sfnt_open_font): Add parameter `woff2_num_faces'.
(sfnt_init_face): Introduce var `woff2_num_faces', and change
`face->root.num_faces' if `woff2_num_faces' is set.

* src/sfnt/sfwoff2.c (woff2_open_font): Validate requested face index
and handle negative face indices.

* src/sfnt/sfwoff2.h (woff2_open_font): Add parameter `num_faces' to
declaration.
2019-08-05 01:53:00 +05:30
Nikhil Ramakrishnan af7d2967d5 [woff2] Improve memory and error handling.
Free up memory after use, and improve error handling.

* src/sfnt/sfwoff2.c: Implement changes.
2019-07-28 19:38:05 +05:30
Nikhil Ramakrishnan befd05c060 Avoid too many calls to `FT_REALLOC'.
We do this by using `totalSfntSize' as an initial reference, and extending
the buffer when required. This reduces rendering time considerably.

* include/freetype/internal/wofftypes.h (WOFF2_HeaderRec): Add
`totalSfntSize', rename `total_sfnt_size' to `actual_sfnt_size'.

* src/sfnt/sfwoff2.c (write_buf): Add parameter `dst_size' to keep track
of and update total size of stream.

(WRITE_SFNT_BUF, WRITE_SFNT_BUF_AT): Modify macros accordingly.

(pad4, store_loca, reconstruct_glyf, reconstruct_hmtx): Update parameters
to accept `sfnt_size'.

(woff2_open_font): Add variable `sfnt_size'. Use WOFF2 header field
`totalSfntSize' as initial reference (if value makes sense) and allocate
`totalSfntSize' bytes for the sfnt stream. `write_buf' handles
reallocation if and when required. Also resize the stream to
`actual_sfnt_size' after reconstruction.
2019-07-18 01:50:16 +05:30
Nikhil Ramakrishnan b9414b4dc6 Reconstruct loca, hmtx and swap out stream.
Add necessary functions to reconstruct loca and hmtx tables (the 2
remaining tables that can have a transform). `woff2_open_font' is now
capable of loading a woff2 font face. This code may still need more
refining and better memory management.

* include/freetype/internal/wofftypes.h (WOFF2_HeaderRec): Add total (final)
size of sfnt stream.

(WOFF2_InfoRec): Add header checksum value.

* src/sfnt/sfobjs.c (sfnt_open_font): Change `face_instance_index' parameter
to its pointer so its value can be modified by `woff2_open_font'.

* src/sfnt/sfwoff2.c: (WRITE_SFNT_BUF_AT): New macro to write into sfnt
buffer at given position.

(write_buf): Add parameter `extend_buf' which allows caller to specify
whether buffer should be reallocated before copying data. Modify macro
`WRITE_SFNT_BUF' accordingly.

(pad4): New function to pad buffer to closest multiple of 4.

(store_loca): Store loca values (provided by `reconstruct_glyf') to output
stream.

(reconstruct_glyf): Calculate loca values and store them.

(reconstruct_hmtx): Reconstruct transformed hmtx table.

(reconstruct_font): Call `reconstruct_hmtx', write table record entries, and
calculate table checksums. Also calculate font checksum and update
`checksumAdjustment' entry in head table.

(woff2_open_font): Open stream for sfnt buffer, swap out input stream and
return.

* src/sfnt/sfwoff2.h (woff2_open_font): Modify parameter to accept pointer
to `face_index'.
2019-07-16 02:45:03 +05:30
Nikhil Ramakrishnan f5a1a74c8d [woff2] Reconstruct transformed `glyf' table.
Reconstruct `glyf' table if it is transformed in the uncompressed table
stream. Also add necessary structures, macros and functions.

* include/freetype/internal/wofftypes.h (WOFF2_InfoRec,
WOFF2_SubstreamRec, WOFF2_PointRec): New structures.

* src/sfnt/sfwoff2.c (READ_255USHORT, READ_BASE128): Use `FT_SET_ERROR'
to set implicit `error' variable.

(WRITE_SHORT): New macro.

(N_CONTOUR_STREAM, N_POINTS_STREAM, FLAG_STREAM, GLYPH_STREAM,
COMPOSITE_STREAM, BBOX_STREAM, INSTRUCTION_STREAM): New macros to refer
to substreams of the transformed `glyf' tables.

(Read255UShort, ReadBase128): Return errors set by `FT_READ_XXX' macros.

(with_sign, safe_int_addition): New functions to add sign to values
based on a flag and perform safe addition respectively.

(triplet_decode): Decode variable-length (flag, xCoordinate, yCoordinate)
triplet for a simple glyph. See

  https://www.w3.org/TR/WOFF2/#triplet_decoding

(store_points): Store decoded points in the glyph buffer.

(compute_bbox): Derive bounding box for a glyph by computing the minimum
and maximum x and y coordinates in the outline.

(reconstruct_glyf): Main routine to reconstruct transformed `glyf' table.

(reconstruct_font): Call `reconstruct_glyf'.

* src/sfnt/sfwoff2.h: Add required constants.

* src/sfnt/woff2tags.h: Move out constants to `sfwoff2.h'.
2019-07-13 03:14:17 +05:30
Nikhil Ramakrishnan 7bf104e759 [woff2] Copy un-transformed tables to sfnt stream.
Copy un-transformed tables to the sfnt stream.

* src/sfnt/sfwoff2.c: (WRITE_SFNT_BUF): New macro.
(write_buf): New function. Extend memory of `dst' buffer and copy bytes
from `src'.
(compute_ULong_sum): New function. Calculate checksum of table.
(woff2_uncompress): Change `FT_Byte* sfnt' to `FT_Byte** sfnt_bytes'.
This has been done because we reallocate memory to `sfnt' multiple
times, which may change the pointer value of `sfnt'. This new pointer
must be propogated back to the caller. Same reason for using a double
pointer in `write_buf'.

* src/sfnt/woff2tags.h: Define default max size to prevent overflow.
2019-07-06 18:05:18 +05:30
Nikhil Ramakrishnan c325089c2f [woff2] Create stream for uncompressed buffer.
Uncompressed buffer is now an `FT_Stream'.

Perform basic checks and start iterating over tables.

* src/sfnt/sfwoff2.c (stream_close, find_table, read_num_hmetrics): New
functions.
(reconstruct_font): Modify params and iterate over tables.
2019-07-05 01:09:52 +05:30
Nikhil Ramakrishnan 0d0bd49be5 [woff2] Handle TTCs and start reconstructing font.
We `handle' TTCs by modifying the `indices' array to point to only those
tables that are part of the requested `face_index'.

Set and use `num_tables' in `WOFF2_TtcFont'.

Start reconstruction of font.

* src/sfnt/sfwoff2.c (reconstruct_font): New function.
2019-07-01 01:29:30 +05:30
Nikhil Ramakrishnan 045c6b1162 [woff2] Get known tags from function.
Change `KnownTags' to a function (`woff2_known_tags'). This avoids
introducing a global constant array. This function returns the specified
index without *any* checks. The caller must ensure that `index' is
within array limits.

* src/sfnt/sfwoff2.c (woff2_open_font): Change `KnownTags[...]' notation
to `woff2_known_tags( ... )'.

* src/sfnt/woff2tags.c: Perform changes.

* src/sfnt/woff2tags.h: Update definitions.
2019-06-30 20:01:20 +05:30
Nikhil Ramakrishnan 6cb1146433 * src/sfnt/sfwoff2.c: Minor. 2019-06-30 19:32:27 +05:30
Nikhil Ramakrishnan f6c4d58ec8 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.
2019-06-30 04:36:44 +05:30
Nikhil Ramakrishnan 6d3d309ae6 * builds/unix/configure.raw: Change argument name to brotli. 2019-06-30 04:15:55 +05:30
Nikhil Ramakrishnan 8e05ab3e2e Add Brotli dependency and required checks.
Brotli is required for decompressing WOFF2 font directory streams.
The library is thus being added as an optional dependency for FreeType.

* builds/unix/configure.raw: Add checks for `libbrotlidec'.

* devel/ftoption.h, include/freetype/config/ftoption.h
(FT_CONFIG_OPTION_USE_BROTLI): New macro.
2019-06-28 01:01:17 +05:30
Nikhil Ramakrishnan 47f009d703 [woff2] Write SFNT Offset table. 2019-06-24 01:07:18 +05:30
Nikhil Ramakrishnan eb229dfabf * src/sfnt/sfwoff2.c: #undef macros. 2019-06-18 23:32:55 +05:30
Nikhil Ramakrishnan e635053045 [woff2] Read table and collection directory.
* include/freetype/internal/wofftypes.h (WOFF2_TtcFontRec): New
structure.
(WOFF2_HeaderRec): Add more fields.

* src/sfnt/woff2.c (READ_255USHORT, READ_BASE128, ROUND4): New macros.
(Read255UShort, CollectionHeaderSize, compute_first_table_offset): New
functions.
(woff2_open_font): Add functionality to read table directory and
collection directory (if present).
2019-06-16 19:09:09 +05:30
Nikhil Ramakrishnan d614e8afbc [sfnt] Include `woff2tags.c' for building.
* src/sfnt/rules.mk: Add `woff2tags.c'.

* src/sfnt/sfnt.c: Include `woff2tags.c'.
2019-06-16 19:09:08 +05:30
Nikhil Ramakrishnan f1083eae5e [sfnt] Add WOFF2 constants.
Add constants required for WOFF2, and known table tags as defined in the
specification. See

  https://www.w3.org/TR/WOFF2/#table_dir_format

for details.

* src/sfnt/woff2tags.c, src/sfnt/woff2tags.h: New files.
2019-06-16 19:09:08 +05:30
Nikhil Ramakrishnan 1b7f95bf70 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.
2019-06-16 19:09:07 +05:30
Nikhil Ramakrishnan c26c91aa39 Add structures for WOFF2.
Add structures and macro for WOFF 2 header and table directory.

* include/freetype/internal/wofftypes.h (WOFF2_HeaderRec,
WOFF2_TableRec_): New structures.

* include/freetype/tttags.h (TTAG_wOF2): New macro.
2019-06-16 19:09:07 +05:30
13 changed files with 2678 additions and 5 deletions

View File

@ -543,6 +543,50 @@ if test x"$with_harfbuzz" = xyes -a "$have_harfbuzz" = no; then
fi
# check for system libbrotlidec
AC_ARG_WITH([brotli],
[AS_HELP_STRING([--with-brotli=@<:@yes|no|auto@:>@],
[Support decompression of WOFF2 streams @<:@default=auto@:>@])],
[], [with_brotli=auto])
have_brotli=no
if test x"$with_brotli" = xyes -o x"$with_brotli" = xauto; then
brotli_pkg="libbrotlidec"
have_brotli_pkg=no
if test x"$BROTLI_CFLAGS" = x -a x"$BROTLI_LIBS" = x; then
PKG_CHECK_EXISTS([$brotli_pkg], [have_brotli_pkg=yes])
fi
PKG_CHECK_MODULES([BROTLI], [$brotli_pkg],
[have_brotli="yes (pkg-config)"], [:])
if test $have_brotli_pkg = yes; then
# we have libbrotlidec.pc
brotli_reqpriv="$brotli_pkg"
brotli_libspriv=
brotli_libsstaticconf=`$PKG_CONFIG --static --libs "$brotli_pkg"`
else
brotli_reqpriv=
if test "$have_brotli" != no; then
# BROTLI_CFLAGS and BROTLI_LIBS are set by the user
brotli_libspriv="$BROTLI_LIBS"
brotli_libsstaticconf="$BROTLI_LIBS"
have_brotli="yes (BROTLI_CFLAGS and BROTLI_LIBS)"
else
# since Brotli is quite a new library we don't fall back to a
# different test;
:
fi
fi
fi
if test x"$with_brotli" = xyes -a "$have_brotli" = no; then
AC_MSG_ERROR([brotli support requested but library not found])
fi
# check for librt
#
# We need `clock_gettime' for the `ftbench' demo program.
@ -992,7 +1036,8 @@ fi
REQUIRES_PRIVATE="$zlib_reqpriv, \
$bzip2_reqpriv, \
$libpng_reqpriv, \
$harfbuzz_reqpriv"
$harfbuzz_reqpriv, \
$brotli_reqpriv"
# beautify
REQUIRES_PRIVATE=`echo "$REQUIRES_PRIVATE" \
| sed -e 's/^ *//' \
@ -1007,6 +1052,7 @@ LIBS_PRIVATE="$zlib_libspriv \
$bzip2_libspriv \
$libpng_libspriv \
$harfbuzz_libspriv \
$brotli_libspriv \
$ft2_extra_libs"
# beautify
LIBS_PRIVATE=`echo "$LIBS_PRIVATE" \
@ -1019,6 +1065,7 @@ LIBSSTATIC_CONFIG="-lfreetype \
$bzip2_libsstaticconf \
$libpng_libsstaticconf \
$harfbuzz_libsstaticconf \
$brotli_libsstaticconf \
$ft2_extra_libs"
# remove -L/usr/lib and -L/usr/lib64 since `freetype-config' adds them later
# on if necessary; also beautify
@ -1083,6 +1130,13 @@ if test "$have_harfbuzz" != no; then
else
ftoption_unset FT_CONFIG_OPTION_USE_HARFBUZZ
fi
if test "$have_brotli" != no; then
CFLAGS="$CFLAGS $BROTLI_CFLAGS"
LDFLAGS="$LDFLAGS $BROTLI_LIBS"
ftoption_set FT_CONFIG_OPTION_USE_BROTLI
else
ftoption_unset FT_CONFIG_OPTION_USE_BROTLI
fi
AC_SUBST([CFLAGS])
AC_SUBST([LDFLAGS])
@ -1129,6 +1183,7 @@ Library configuration:
bzip2: $have_bzip2
libpng: $have_libpng
harfbuzz: $have_harfbuzz
brotli: $have_brotli
])
# Warn if docwriter is not installed

View File

@ -292,6 +292,22 @@ FT_BEGIN_HEADER
#define FT_CONFIG_OPTION_USE_HARFBUZZ
/**************************************************************************
*
* Brotli support.
*
* FreeType uses the Brotli library to provide support for decompressing
* WOFF2 streams.
*
* Define this macro if you want to enable this 'feature'.
*
* If you use a build system like cmake or the `configure` script,
* options set by those programs have precedence, overwriting the value
* here with the configured one.
*/
#define FT_CONFIG_OPTION_USE_BROTLI
/**************************************************************************
*
* Glyph Postscript Names handling

View File

@ -292,6 +292,22 @@ FT_BEGIN_HEADER
/* #define FT_CONFIG_OPTION_USE_HARFBUZZ */
/**************************************************************************
*
* Brotli support.
*
* FreeType uses the Brotli library to provide support for decompressing
* WOFF2 streams.
*
* Define this macro if you want to enable this 'feature'.
*
* If you use a build system like cmake or the `configure` script,
* options set by those programs have precedence, overwriting the value
* here with the configured one.
*/
#define FT_CONFIG_OPTION_USE_BROTLI
/**************************************************************************
*
* Glyph Postscript Names handling

View File

@ -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) */

View File

@ -104,6 +104,194 @@ FT_BEGIN_HEADER
} WOFF_TableRec, *WOFF_Table;
/**************************************************************************
*
* @struct:
* WOFF2_TtcFontRec
*
* @description:
* Metadata for a TTC font entry in WOFF2.
*
* @fields:
* flavor ::
* TTC font flavor.
*
* num_tables ::
* Number of tables in TTC, indicating number of elements in
* `table_indices`.
*
* table_indices ::
* Array of table indices for each TTC font.
*/
typedef struct WOFF2_TtcFontRec_
{
FT_ULong flavor;
FT_UShort num_tables;
FT_UShort* table_indices;
} WOFF2_TtcFontRec, *WOFF2_TtcFont;
/**************************************************************************
*
* @struct:
* WOFF2_HeaderRec
*
* @description:
* WOFF2 file format header.
*
* @fields:
* See
*
* https://www.w3.org/TR/WOFF2/#woff20Header
*
* @note:
* We don't care about the fields `reserved`, `majorVersion` and
* `minorVersion`, so they are not included. The `totalSfntSize` field
* does not necessarily represent the actual size of the uncompressed
* SFNT font stream, so that is used as a reference value instead.
*/
typedef struct WOFF2_HeaderRec_
{
FT_ULong signature;
FT_ULong flavor;
FT_ULong length;
FT_UShort num_tables;
FT_ULong totalSfntSize;
FT_ULong totalCompressedSize;
FT_ULong metaOffset;
FT_ULong metaLength;
FT_ULong metaOrigLength;
FT_ULong privOffset;
FT_ULong privLength;
FT_ULong uncompressed_size; /* uncompressed brotli stream size */
FT_ULong compressed_offset; /* compressed stream offset */
FT_ULong header_version; /* version of original TTC Header */
FT_UShort num_fonts; /* number of fonts in TTC */
FT_ULong actual_sfnt_size; /* actual size of sfnt stream */
WOFF2_TtcFont ttc_fonts; /* metadata for fonts in a TTC */
} WOFF2_HeaderRec, *WOFF2_Header;
/**************************************************************************
*
* @struct:
* WOFF2_InfoRec
*
* @description:
* Metadata for WOFF2 font that may be required for reconstruction of
* sfnt tables.
*
* @fields:
* header_checksum ::
* Checksum of SFNT offset table.
*
* num_glyphs ::
* Number of glyphs in the font.
*
* num_hmetrics ::
* `numberOfHMetrics` field in the 'hhea' table.
*
* x_mins ::
* `xMin` values of glyph bounding box.
*/
typedef struct WOFF2_InfoRec_
{
FT_ULong header_checksum;
FT_UShort num_glyphs;
FT_UShort num_hmetrics;
FT_Short* x_mins;
} WOFF2_InfoRec, *WOFF2_Info;
/**************************************************************************
*
* @struct:
* WOFF2_TableRec
*
* @description:
* This structure describes a given table of a WOFF2 font.
*
* @fields:
* See
*
* https://www.w3.org/TR/WOFF2/#table_dir_format
*/
typedef struct WOFF2_TableRec_
{
FT_Byte FlagByte; /* table type and flags */
FT_ULong Tag; /* table file offset */
FT_ULong dst_length; /* uncompressed table length */
FT_ULong TransformLength; /* transformed length */
FT_ULong flags; /* calculated flags */
FT_ULong src_offset; /* compressed table offset */
FT_ULong src_length; /* compressed table length */
FT_ULong dst_offset; /* uncompressed table offset */
} WOFF2_TableRec, *WOFF2_Table;
/**************************************************************************
*
* @struct:
* WOFF2_SubstreamRec
*
* @description:
* This structure stores information about a substream in the transformed
* 'glyf' table in a WOFF2 stream.
*
* @fields:
* start ::
* Beginning of the substream relative to uncompressed table stream.
*
* offset ::
* Offset of the substream relative to uncompressed table stream.
*
* size ::
* Size of the substream.
*/
typedef struct WOFF2_SubstreamRec_
{
FT_ULong start;
FT_ULong offset;
FT_ULong size;
} WOFF2_SubstreamRec, *WOFF2_Substream;
/**************************************************************************
*
* @struct:
* WOFF2_PointRec
*
* @description:
* This structure stores information about a point in the transformed
* 'glyf' table in a WOFF2 stream.
*
* @fields:
* x ::
* x-coordinate.
*
* y ::
* y-coordinate.
*
* on_curve ::
* Whether point is on-curve.
*/
typedef struct WOFF2_PointRec_
{
FT_Int x;
FT_Int y;
FT_Bool on_curve;
} WOFF2_PointRec, *WOFF2_Point;
FT_END_HEADER
#endif /* WOFFTYPES_H_ */

View File

@ -107,6 +107,7 @@ FT_BEGIN_HEADER
#define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' )
#define TTAG_VVAR FT_MAKE_TAG( 'V', 'V', 'A', 'R' )
#define TTAG_wOFF FT_MAKE_TAG( 'w', 'O', 'F', 'F' )
#define TTAG_wOF2 FT_MAKE_TAG( 'w', 'O', 'F', '2' )
/* used by "Keyboard.dfont" on legacy Mac OS X */
#define TTAG_0xA5kbd FT_MAKE_TAG( 0xA5, 'k', 'b', 'd' )

View File

@ -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 \
@ -40,7 +41,8 @@ SFNT_DRV_SRC := $(SFNT_DIR)/pngshim.c \
$(SFNT_DIR)/ttload.c \
$(SFNT_DIR)/ttmtx.c \
$(SFNT_DIR)/ttpost.c \
$(SFNT_DIR)/ttsbit.c
$(SFNT_DIR)/ttsbit.c \
$(SFNT_DIR)/woff2tags.c
# SFNT driver headers
#

View File

@ -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"
@ -33,6 +34,7 @@
#include "ttmtx.c"
#include "ttpost.c"
#include "ttsbit.c"
#include "woff2tags.c"
/* END */

View File

@ -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
@ -341,7 +342,9 @@
/* 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_Long* woff2_num_faces )
{
FT_Memory memory = stream->memory;
FT_Error error;
@ -385,6 +388,25 @@
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,
face_instance_index,
woff2_num_faces );
if ( error )
return error;
/* Swap out stream and retry! */
stream = face->root.stream;
goto retry;
}
if ( tag != 0x00010000UL &&
tag != TTAG_ttcf &&
tag != TTAG_OTTO &&
@ -461,9 +483,10 @@
FT_Parameter* params )
{
FT_Error error;
FT_Library library = face->root.driver->root.library;
FT_Library library = face->root.driver->root.library;
SFNT_Service sfnt;
FT_Int face_index;
FT_Long woff2_num_faces = 0;
/* for now, parameters are unused */
@ -514,7 +537,10 @@
FT_TRACE2(( "SFNT driver\n" ));
error = sfnt_open_font( stream, face );
error = sfnt_open_font( stream,
face,
&face_instance_index,
&woff2_num_faces );
if ( error )
return error;
@ -689,6 +715,10 @@
face->root.num_faces = face->ttc_header.count;
face->root.face_index = face_instance_index;
/* `num_faces' for a WOFF2 needs to be handled separately. */
if ( woff2_num_faces )
face->root.num_faces = woff2_num_faces;
return error;
}

2146
src/sfnt/sfwoff2.c Normal file

File diff suppressed because it is too large Load Diff

76
src/sfnt/sfwoff2.h Normal file
View File

@ -0,0 +1,76 @@
/****************************************************************************
*
* 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
/* Leave the first byte open to store flag_byte. */
#define WOFF2_FLAGS_TRANSFORM 1 << 8
#define WOFF2_SFNT_HEADER_SIZE 12
#define WOFF2_SFNT_ENTRY_SIZE 16
/* Suggested max size for output. */
#define WOFF2_DEFAULT_MAX_SIZE 30 * 1024 * 1024
/* 98% of Google Fonts have no glyph above 5k bytes. */
#define WOFF2_DEFAULT_GLYPH_BUF 5120
/* Composite glyph flags */
/* See CompositeGlyph.java in `sfntly' for full definitions */
#define FLAG_ARG_1_AND_2_ARE_WORDS 1 << 0
#define FLAG_WE_HAVE_A_SCALE 1 << 3
#define FLAG_MORE_COMPONENTS 1 << 5
#define FLAG_WE_HAVE_AN_X_AND_Y_SCALE 1 << 6
#define FLAG_WE_HAVE_A_TWO_BY_TWO 1 << 7
#define FLAG_WE_HAVE_INSTRUCTIONS 1 << 8
/* Simple glyph flags */
#define GLYF_ON_CURVE 1 << 0
#define GLYF_X_SHORT 1 << 1
#define GLYF_Y_SHORT 1 << 2
#define GLYF_REPEAT 1 << 3
#define GLYF_THIS_X_IS_SAME 1 << 4
#define GLYF_THIS_Y_IS_SAME 1 << 5
/* Other constants */
#define CONTOUR_OFFSET_END_POINT 10
FT_LOCAL( FT_Error )
woff2_open_font( FT_Stream stream,
TT_Face face,
FT_Int* face_index,
FT_Long* num_faces );
FT_END_HEADER
#endif /* SFWOFF2_H_ */
/* END */

101
src/sfnt/woff2tags.c Normal file
View File

@ -0,0 +1,101 @@
/****************************************************************************
*
* woff2tags.c
*
* WOFF2 Font table tags (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 "sfwoff.h"
#include FT_TRUETYPE_TAGS_H
/* Return tag from index in the order given in WOFF2 specification. */
FT_LOCAL_DEF( FT_ULong )
woff2_known_tags( FT_Byte index )
{
const FT_ULong known_tags[63] =
{
FT_MAKE_TAG('c', 'm', 'a', 'p'), /* 0 */
FT_MAKE_TAG('h', 'e', 'a', 'd'), /* 1 */
FT_MAKE_TAG('h', 'h', 'e', 'a'), /* 2 */
FT_MAKE_TAG('h', 'm', 't', 'x'), /* 3 */
FT_MAKE_TAG('m', 'a', 'x', 'p'), /* 4 */
FT_MAKE_TAG('n', 'a', 'm', 'e'), /* 5 */
FT_MAKE_TAG('O', 'S', '/', '2'), /* 6 */
FT_MAKE_TAG('p', 'o', 's', 't'), /* 7 */
FT_MAKE_TAG('c', 'v', 't', ' '), /* 8 */
FT_MAKE_TAG('f', 'p', 'g', 'm'), /* 9 */
FT_MAKE_TAG('g', 'l', 'y', 'f'), /* 10 */
FT_MAKE_TAG('l', 'o', 'c', 'a'), /* 11 */
FT_MAKE_TAG('p', 'r', 'e', 'p'), /* 12 */
FT_MAKE_TAG('C', 'F', 'F', ' '), /* 13 */
FT_MAKE_TAG('V', 'O', 'R', 'G'), /* 14 */
FT_MAKE_TAG('E', 'B', 'D', 'T'), /* 15 */
FT_MAKE_TAG('E', 'B', 'L', 'C'), /* 16 */
FT_MAKE_TAG('g', 'a', 's', 'p'), /* 17 */
FT_MAKE_TAG('h', 'd', 'm', 'x'), /* 18 */
FT_MAKE_TAG('k', 'e', 'r', 'n'), /* 19 */
FT_MAKE_TAG('L', 'T', 'S', 'H'), /* 20 */
FT_MAKE_TAG('P', 'C', 'L', 'T'), /* 21 */
FT_MAKE_TAG('V', 'D', 'M', 'X'), /* 22 */
FT_MAKE_TAG('v', 'h', 'e', 'a'), /* 23 */
FT_MAKE_TAG('v', 'm', 't', 'x'), /* 24 */
FT_MAKE_TAG('B', 'A', 'S', 'E'), /* 25 */
FT_MAKE_TAG('G', 'D', 'E', 'F'), /* 26 */
FT_MAKE_TAG('G', 'P', 'O', 'S'), /* 27 */
FT_MAKE_TAG('G', 'S', 'U', 'B'), /* 28 */
FT_MAKE_TAG('E', 'B', 'S', 'C'), /* 29 */
FT_MAKE_TAG('J', 'S', 'T', 'F'), /* 30 */
FT_MAKE_TAG('M', 'A', 'T', 'H'), /* 31 */
FT_MAKE_TAG('C', 'B', 'D', 'T'), /* 32 */
FT_MAKE_TAG('C', 'B', 'L', 'C'), /* 33 */
FT_MAKE_TAG('C', 'O', 'L', 'R'), /* 34 */
FT_MAKE_TAG('C', 'P', 'A', 'L'), /* 35 */
FT_MAKE_TAG('S', 'V', 'G', ' '), /* 36 */
FT_MAKE_TAG('s', 'b', 'i', 'x'), /* 37 */
FT_MAKE_TAG('a', 'c', 'n', 't'), /* 38 */
FT_MAKE_TAG('a', 'v', 'a', 'r'), /* 39 */
FT_MAKE_TAG('b', 'd', 'a', 't'), /* 40 */
FT_MAKE_TAG('b', 'l', 'o', 'c'), /* 41 */
FT_MAKE_TAG('b', 's', 'l', 'n'), /* 42 */
FT_MAKE_TAG('c', 'v', 'a', 'r'), /* 43 */
FT_MAKE_TAG('f', 'd', 's', 'c'), /* 44 */
FT_MAKE_TAG('f', 'e', 'a', 't'), /* 45 */
FT_MAKE_TAG('f', 'm', 't', 'x'), /* 46 */
FT_MAKE_TAG('f', 'v', 'a', 'r'), /* 47 */
FT_MAKE_TAG('g', 'v', 'a', 'r'), /* 48 */
FT_MAKE_TAG('h', 's', 't', 'y'), /* 49 */
FT_MAKE_TAG('j', 'u', 's', 't'), /* 50 */
FT_MAKE_TAG('l', 'c', 'a', 'r'), /* 51 */
FT_MAKE_TAG('m', 'o', 'r', 't'), /* 52 */
FT_MAKE_TAG('m', 'o', 'r', 'x'), /* 53 */
FT_MAKE_TAG('o', 'p', 'b', 'd'), /* 54 */
FT_MAKE_TAG('p', 'r', 'o', 'p'), /* 55 */
FT_MAKE_TAG('t', 'r', 'a', 'k'), /* 56 */
FT_MAKE_TAG('Z', 'a', 'p', 'f'), /* 57 */
FT_MAKE_TAG('S', 'i', 'l', 'f'), /* 58 */
FT_MAKE_TAG('G', 'l', 'a', 't'), /* 59 */
FT_MAKE_TAG('G', 'l', 'o', 'c'), /* 60 */
FT_MAKE_TAG('F', 'e', 'a', 't'), /* 61 */
FT_MAKE_TAG('S', 'i', 'l', 'l'), /* 62 */
};
if ( index < 0 || index > 62 )
return 0;
return known_tags[index];
}
/* END */

39
src/sfnt/woff2tags.h Normal file
View File

@ -0,0 +1,39 @@
/****************************************************************************
*
* woff2tags.h
*
* WOFFF2 Font table tags (specification).
*
* Copyright (C) 1996-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 WOFF2TAGS_H
#define WOFF2TAGS_H
#include <ft2build.h>
#include FT_INTERNAL_OBJECTS_H
FT_BEGIN_HEADER
FT_LOCAL( FT_ULong )
woff2_known_tags( FT_Byte index );
FT_END_HEADER
#endif /* WOFF2TAGS_H */
/* END */