diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h index a6bb667e3..db12f836b 100644 --- a/include/freetype/freetype.h +++ b/include/freetype/freetype.h @@ -141,6 +141,7 @@ FT_BEGIN_HEADER * FT_FACE_FLAG_GLYPH_NAMES * FT_FACE_FLAG_EXTERNAL_STREAM * FT_FACE_FLAG_HINTER + * FT_FACE_FLAG_SVG * * FT_HAS_HORIZONTAL * FT_HAS_VERTICAL @@ -1167,6 +1168,10 @@ FT_BEGIN_HEADER * table only if the native TrueType hinting engine (with the bytecode * interpreter) is available and active. * + * FT_FACE_FLAG_SVG :: + * The font file has an SVG table. The presence of an SVG table + * indicate the presence of OT-SVG glyphs. + * * FT_FACE_FLAG_CID_KEYED :: * The face is CID-keyed. In that case, the face is not accessed by * glyph indices but by CID values. For subsetted CID-keyed fonts this @@ -1223,6 +1228,7 @@ FT_BEGIN_HEADER #define FT_FACE_FLAG_TRICKY ( 1L << 13 ) #define FT_FACE_FLAG_COLOR ( 1L << 14 ) #define FT_FACE_FLAG_VARIATION ( 1L << 15 ) +#define FT_FACE_FLAG_SVG ( 1L << 16 ) /************************************************************************** diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h index b19241c30..fbc29d3a2 100644 --- a/include/freetype/internal/sfnt.h +++ b/include/freetype/internal/sfnt.h @@ -778,6 +778,10 @@ FT_BEGIN_HEADER TT_Get_Name_Func get_name; TT_Get_Name_ID_Func get_name_id; + /* OpenType SVG support */ + TT_Load_Table_Func load_svg; + TT_Free_Table_Func free_svg; + } SFNT_Interface; @@ -824,7 +828,9 @@ FT_BEGIN_HEADER colr_blend_, \ get_metrics_, \ get_name_, \ - get_name_id_ ) \ + get_name_id_, \ + load_svg_, \ + free_svg_ ) \ static const SFNT_Interface class_ = \ { \ goto_table_, \ @@ -864,7 +870,9 @@ FT_BEGIN_HEADER colr_blend_, \ get_metrics_, \ get_name_, \ - get_name_id_ \ + get_name_id_, \ + load_svg_, \ + free_svg_ \ }; diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h index 23db240e7..d092dbade 100644 --- a/include/freetype/internal/tttypes.h +++ b/include/freetype/internal/tttypes.h @@ -1645,6 +1645,9 @@ FT_BEGIN_HEADER void* cpal; void* colr; + /* OpenType SVG glyph support */ + void* svg; + } TT_FaceRec; diff --git a/include/freetype/tttags.h b/include/freetype/tttags.h index bd0986eff..2ce7cebe0 100644 --- a/include/freetype/tttags.h +++ b/include/freetype/tttags.h @@ -96,6 +96,7 @@ FT_BEGIN_HEADER #define TTAG_sbix FT_MAKE_TAG( 's', 'b', 'i', 'x' ) #define TTAG_sfnt FT_MAKE_TAG( 's', 'f', 'n', 't' ) #define TTAG_SING FT_MAKE_TAG( 'S', 'I', 'N', 'G' ) +#define TTAG_SVG FT_MAKE_TAG( 'S', 'V', 'G', ' ' ) #define TTAG_trak FT_MAKE_TAG( 't', 'r', 'a', 'k' ) #define TTAG_true FT_MAKE_TAG( 't', 'r', 'u', 'e' ) #define TTAG_ttc FT_MAKE_TAG( 't', 't', 'c', ' ' ) diff --git a/src/sfnt/sfdriver.c b/src/sfnt/sfdriver.c index 261168528..dec953c4b 100644 --- a/src/sfnt/sfdriver.c +++ b/src/sfnt/sfdriver.c @@ -37,6 +37,10 @@ #include "ttcpal.h" #endif +#ifdef FT_CONFIG_OPTION_SVG +#include "ttsvg.h" +#endif + #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES #include "ttpost.h" #endif @@ -1214,6 +1218,12 @@ #define PUT_COLOR_LAYERS( a ) NULL #endif +#ifdef FT_CONFIG_OPTION_SVG +#define PUT_SVG_SUPPORT( a ) a +#else +#define PUT_SVG_SUPPORT( a ) NULL +#endif + #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES #define PUT_PS_NAMES( a ) a #else @@ -1294,7 +1304,12 @@ tt_face_get_metrics, /* TT_Get_Metrics_Func get_metrics */ tt_face_get_name, /* TT_Get_Name_Func get_name */ - sfnt_get_name_id /* TT_Get_Name_ID_Func get_name_id */ + sfnt_get_name_id, /* TT_Get_Name_ID_Func get_name_id */ + + PUT_SVG_SUPPORT( tt_face_load_svg ), + /* TT_Load_Table_Func load_svg */ + PUT_SVG_SUPPORT( tt_face_free_svg ) + /* TT_Free_Table_Func free_svg */ ) diff --git a/src/sfnt/sfnt.c b/src/sfnt/sfnt.c index b4faf34a3..16ba899a7 100644 --- a/src/sfnt/sfnt.c +++ b/src/sfnt/sfnt.c @@ -27,6 +27,7 @@ #include "ttcmap.c" #include "ttcolr.c" #include "ttcpal.c" +#include "ttsvg.c" #include "ttkern.c" #include "ttload.c" diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c index 6edf3ae1d..c865e2cb0 100644 --- a/src/sfnt/sfobjs.c +++ b/src/sfnt/sfobjs.c @@ -953,6 +953,11 @@ LOAD_( colr ); } +#ifdef FT_CONFIG_OPTION_SVG + if ( sfnt->load_svg ) + LOAD_( svg ); +#endif + /* consider the pclt, kerning, and gasp tables as optional */ LOAD_( pclt ); LOAD_( gasp ); @@ -1372,6 +1377,12 @@ sfnt->free_cpal( face ); sfnt->free_colr( face ); } + +#ifdef FT_CONFIG_OPTION_SVG + /* free svg data */ + if ( sfnt->free_svg ) + sfnt->free_svg( face ); +#endif } #ifdef TT_CONFIG_OPTION_BDF diff --git a/src/sfnt/ttsvg.c b/src/sfnt/ttsvg.c new file mode 100644 index 000000000..546446b6f --- /dev/null +++ b/src/sfnt/ttsvg.c @@ -0,0 +1,129 @@ +/**************************************************************************** + * + * ttsvg.c + * + * OpenType SVG Color (specification). + * + * Copyright (C) 2018-2019 by + * David Turner, Robert Wilhelm, Werner Lemberg and Moazin Khatti. + * + * 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. + * + */ + + + /************************************************************************** + * + * `SVG' table specification: + * + * https://docs.microsoft.com/en-us/typography/opentype/spec/svg + * + */ + +#include +#include FT_INTERNAL_STREAM_H +#include FT_INTERNAL_OBJECTS_H +#include FT_TRUETYPE_TAGS_H + +#ifdef FT_CONFIG_OPTION_SVG + +#include "ttsvg.h" + + typedef struct Svg_ + { + FT_UShort version; /* Table version (starting at 0) */ + FT_UShort num_entries; /* Number of SVG document records */ + /* Pointer to the starting of SVG Document List */ + FT_Byte* svg_doc_list; + void* table; /* Memory that backs up SVG */ + FT_ULong table_size; + } Svg; + + + FT_LOCAL_DEF( FT_Error ) + tt_face_load_svg( TT_Face face, + FT_Stream stream ) + { + FT_Error error; + FT_Memory memory = face->root.memory; + + FT_ULong table_size; + FT_Byte* table = NULL; + FT_Byte* p = NULL; + + Svg* svg = NULL; + + FT_ULong offsetToSVGDocumentList; + + + error = face->goto_table( face, TTAG_SVG, stream, &table_size ); + if( error ) + goto NoSVG; + + if( FT_FRAME_EXTRACT( table_size, table )) + goto NoSVG; + + /* Allocate the memory for the Svg object */ + if( FT_NEW( svg ) ) + goto NoSVG; + + p = table; + svg->version = FT_NEXT_USHORT( p ); + offsetToSVGDocumentList = FT_NEXT_ULONG( p ); + + if( offsetToSVGDocumentList == 0 ) + goto InvalidTable; + + svg->svg_doc_list = (FT_Byte*)( table + offsetToSVGDocumentList ); + + p = svg->svg_doc_list; + svg->num_entries = FT_NEXT_USHORT( p ); + + FT_TRACE3(( "version: %d\n", svg->version )); + FT_TRACE3(( "num entiries: %d\n", svg->num_entries )); + + svg->table = table; + svg->table_size = table_size; + + face->svg = svg; + + face->root.face_flags |= FT_FACE_FLAG_SVG; + + return FT_Err_Ok; + + InvalidTable: + error = FT_THROW( Invalid_Table ); + + NoSVG: + FT_FRAME_RELEASE( table ); + FT_FREE( svg ); + face->svg = NULL; + + return error; + } + + FT_LOCAL_DEF( void ) + tt_face_free_svg( TT_Face face ) + { + FT_Memory memory = face->root.memory; + FT_Stream stream = face->root.stream; + Svg* svg = (Svg*) face->svg; + + + if( svg ) + { + FT_FRAME_RELEASE( svg->table ); + FT_FREE( svg ); + } + } + +#else /* !FT_CONFIG_OPTION_SVG */ + + /* ANSI C doesn't like empty source files */ + typedef int _tt_svg_dummy; + +#endif /* !FT_CONFIG_OPTION_SVG */ diff --git a/src/sfnt/ttsvg.h b/src/sfnt/ttsvg.h new file mode 100644 index 000000000..493d72aa0 --- /dev/null +++ b/src/sfnt/ttsvg.h @@ -0,0 +1,35 @@ +/**************************************************************************** + * + * ttsvg.h + * + * OpenType SVG Color (specification). + * + * Copyright (C) 2018-2019 by + * David Turner, Robert Wilhelm, Werner Lemberg and Moazin Khatti. + * + * 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 __TTSVG_H__ +#define __TTSVG_H__ + +#include + +FT_BEGIN_HEADER + + FT_LOCAL( FT_Error ) + tt_face_load_svg( TT_Face face, + FT_Stream stream ); + + FT_LOCAL( void ) + tt_face_free_svg( TT_Face face ); + +FT_END_HEADER + +#endif /* __TTSVG_H__ */ +/* END */