Compare commits

...

37 Commits

Author SHA1 Message Date
Moazin Khatti f40ef225a2 Instead of individual properties. Just use one that
takes pointer to the hooks structure.
2019-07-18 00:05:49 +05:00
Moazin Khatti d94f52b0c6 Use `FT_Property_Set' to set the hooks. One less API function. 2019-07-17 23:31:59 +05:00
Moazin Khatti 02b14b7824 Public interface should remain same whether
`FT_CONFIG_OPTION_SVG' is set or not.
2019-07-17 15:57:02 +05:00
Moazin Khatti def48796f4 Added `FT_CONFIG_OPTION_SVG'. 2019-07-17 12:22:47 +05:00
Moazin Khatti 41a1572f33 Documentation formatting improvement. 2019-07-11 15:52:31 +05:00
Moazin Khatti 6e05128713 Better naming used. 2019-07-11 14:09:43 +05:00
Moazin Khatti e11721ee02 Forgot an `else', fix that. 2019-07-11 14:09:43 +05:00
Moazin Khatti 509ae10ca5 Memory allocation for `state' of renderer should be performed
on the SVG port side not the FT size. Minor doc fixes.
2019-07-11 14:09:43 +05:00
Moazin Khatti 9ff1a33826 Remove unnecessary code from `FT_Render_Glyph_Internal'. 2019-07-11 14:09:43 +05:00
Moazin Khatti 2e9e84193d Let FT handle the memory management for rendering port's state
and the image buffer.

State has been moved inside the library structure. A new hook
function has been added to query the size needed for the state
structure and this allocation is performed by FT. Memory alloc.
for the image buffer is also being done by FT so that it can later
free it easily.

* include/freetype/svgrenderer.h: Small doc fixes. Addition of two
new hooks. `SVG_Lib_Get_State_Size' and `SVG_Lib_Get_Buffer_Size'.

* src/base/ftglyph.c (FT_Glyph_To_Bitmap): Small bug fix. Memory
was being initialized before library.

* src/base/ftobjs.c (FT_Set_Svg_Hooks): Adjust the code for new
hook functions.

* src/svg/ftsvg.c: Adjust the code for new hook functions. Perform
all memory allocations needed by the rendering port from FreeType
side.

* src/svg/svgtypes.c: Add the new hooks in the hook structure.
2019-07-11 14:09:43 +05:00
Moazin Khatti b85698d447 Store the rendering port's state in library.
Before this commit, the state of a rendering port was being
held globally. Now, it'll be stored in library->svg_renderer_state.
2019-07-11 14:09:43 +05:00
Moazin Khatti f9b0bb6b95 Minor fixes. 2019-07-11 14:09:43 +05:00
Moazin Khatti 11f3c827b8 Add `start_glyph_id' and `end_glyph_id'.
These two fields are added to `FT_SvgGlyphRec' and
`FT_SVG_DocumentRec'. This is to allow the rendering port to create
a caching mechanism.
2019-07-11 14:09:43 +05:00
Moazin Khatti 5f2dcadbf2 Add a `units_per_EM' field.
A field `units_per_EM' is added to `FT_SVG_DocumentRec' and
`FT_SvgGlyphRec'. This is needed because the renderer needs this
info to properly scale the SVGs if the viewbox width and height
differ from `face->units_per_EM'. Face object can't be accessed
because of the restrictions put by `FT_Glyph_To_Bitmap' thus this
has to be provided separately just like `metrics'.
2019-07-11 14:09:43 +05:00
Moazin Khatti c9308ac171 Do proper memory freeing to prevent leaks.
* include/freetype/internal/ftobjs.h: Create a new flag named
`FT_GLYPH_OWN_GZIP_SVG' to indicate that `svg_document' in
`slot->other' is GZIP compressed and has to be freed later.

* src/base/ftglyph.c: Minor styling.

* src/base/ftobjs.c: Add code to free memory that was previously
allocated for storing GZIP compressed SVG documents.

* src/sfnt/ttsvg.c: Set the `FT_GLYPH_OWN_GZIP_SVG' flag if the
document is GZIP compressed.
2019-07-11 14:09:43 +05:00
Moazin Khatti 8f36343498 Minor. Add documentation. 2019-07-11 14:09:43 +05:00
Moazin Khatti f70f02cdd1 * src/sfnt/ttsvg.c (tt_face_load_svg_doc): Minor fix. Don't return
immediately in case of Gzip compressed SVG documents.
2019-07-11 14:09:43 +05:00
Moazin Khatti 72eb3b3a9d Properly free memory of SVG document referenced in `slot->other'.
* include/freetype/freetype.h: Add `FT_FACE_FLAG_SVG' to indicate
the presence of an SVG table in the face.

* src/base/ftobjs.c (ft_glyphslot_init): Allocate memory for
`FT_SVG_Document' in `slot->other' if an SVG table exists in the
face.
(ft_glyphslot_clear): Clear `slot->other' only if the font doesn't
have an SVG table.
(ft_glyphslot_done): Free the memory at `slot->other' if the face
has an SVG table.

* src/base/ttsvg.c (tt_face_load_svg): Set `FT_FACE_FLAG_SVG'.
(tt_face_load_svg_doc): Don't allocate the memory.
2019-07-11 14:09:43 +05:00
Moazin Khatti aec7ec2a62 Enable FreeType memory debugger. 2019-07-11 14:09:43 +05:00
Moazin Khatti 71a8aaa807 [cache] Consider `FT_GLYPH_FORMAT_SVG' a valid format. 2019-07-11 14:09:43 +05:00
Moazin Khatti 4288f4a70a Minor changes.
* src/base/ftobjs.c (FT_Load_Glyph): Use the recrusive call with
`FT_LOAD_NO_SCALE' so that the loaded data is unscaled.

* src/base/ftobjs.c (FT_Render_Glyph_Internal): Change the format
to bitmap once an SVG glyph is successfully rendered.

* src/sfnt/ttsvg.c (tt_face_load_svg_doc): Make sure metrics are
grabbed. Scale `horiAdvance' and `vertAdvance' properly and
convert them to 26.6 format.
2019-07-11 14:09:43 +05:00
Moazin Khatti 2a9f8aea1f Adds support for SVG glyphs to Glyph Management API. 2019-07-11 14:09:43 +05:00
Moazin Khatti 7e3c438166 Make sure `FT_Set_Svg_Hooks' is exported properly. 2019-07-11 14:09:43 +05:00
Moazin Khatti 1b494f52fb Adds size information to `FT_SVG_DocumentRec'.
This is necessary because the document itself contains no
sizing information. Outline glyphs encapsulate the sizing
information in the outlines by scaling them. That is not
possible here. One could access them from the face object
reference inside a glyph slot, but when the function
`FT_Glyph_To_Bitmap' creates a dummy slot it can not put
a face object reference in it. Thus, it's better to store
the size information here.
2019-07-11 14:09:43 +05:00
Moazin Khatti 204329b18e [ot-svg] Create an SVG Document structure for use in `other' field
of `FT_GlyphSlot'.
2019-07-11 14:09:43 +05:00
Moazin Khatti a4f1da1572 Removes trailing white spaces. 2019-07-11 14:09:43 +05:00
Moazin Khatti e676c86e92 Reverts the changes made in the structure of `TT_GlyphSlot' 2019-07-11 14:09:43 +05:00
Moazin Khatti 5381d51956 [ot-svg] Silly mistake fix.
Instead of an `FT_Library' instance, `FT_Module' is supposed
to be passed.
2019-07-11 14:09:43 +05:00
Moazin Khatti 3560126a3a Minor. Better documentation. Adds TODOs for letter. 2019-07-11 14:09:42 +05:00
Moazin Khatti 8f256de2d8 [ot-svg] Creates hooks mechanism in SVG Renderer.
* include/freetype/config/ftheader.h: New macro `FT_SVG_RENDERER_H'
for `freetype/svgrenderer.h'.

* include/freetype/svgrenderer.h: New file to store SVG specific
function types, SVG interface and `FT_Set_Svg_Hooks'.

* src/base/ftobjs.c: Adds implementation of `FT_Set_Svg_Hooks'.

* src/svg/ftsvg.c: Creates `svg_renderer_interface'.

* src/svg/svgtypes.c: Moves hook function types to
`FT_SVG_RENDERER_H'. Adds a hook for svg rendering. Temporary.
2019-07-11 14:09:42 +05:00
Moazin Khatti 7915e5e102 Barebones of an SVG rendering module and making it part of the build system 2019-07-11 14:09:42 +05:00
Moazin Khatti 1ab8251ff1 Support OT-SVG fonts with CFF outlines 2019-07-11 14:09:42 +05:00
Moazin Khatti 68d1cab0e1 Very crude way to handle SVG data with only TTF outlined OT fonts. Gonna revert soon. 2019-07-11 14:09:42 +05:00
Moazin Khatti 7b9673dd01 Added FT_GLYPH_FORMAT_SVG 2019-07-11 14:09:42 +05:00
Moazin Khatti 3201792dba Created Svg type and the load/free funcs inside sfnt interface 2019-07-11 14:09:42 +05:00
Moazin Khatti f61fa9934f Added the SVG tag 2019-07-11 14:09:42 +05:00
Moazin Khatti 77726abc41 turned on trace mode and added tags file in gitignore 2019-07-11 14:09:42 +05:00
28 changed files with 1309 additions and 10 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
config.mk
objs/vc2010/
build
tags

View File

@ -547,6 +547,19 @@
#define FT_BITMAP_H <freetype/ftbitmap.h>
/**************************************************************************
*
* @macro:
* FT_SVG_RENDER_H
*
* @description:
* A macro used in `#include` statements to name the file containing the
* API of the SVG Renderer Module.
*
*/
#define FT_SVG_RENDER_H <freetype/svgrender.h>
/**************************************************************************
*
* @macro:

View File

@ -414,7 +414,7 @@ FT_BEGIN_HEADER
* them for certain configurations only.
*/
/* #define FT_DEBUG_LEVEL_ERROR */
/* #define FT_DEBUG_LEVEL_TRACE */
#define FT_DEBUG_LEVEL_TRACE
/**************************************************************************
@ -473,7 +473,7 @@ FT_BEGIN_HEADER
* Do not `#undef` this macro here since the build system might define it
* for certain configurations only.
*/
/* #define FT_DEBUG_MEMORY */
#define FT_DEBUG_MEMORY
/**************************************************************************
@ -493,6 +493,15 @@ FT_BEGIN_HEADER
#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS
/**************************************************************************
*
* OpenType SVG Glyph Support
*
* If this macro is set, OpenType SVG glyphs will be supported.
*/
#define FT_CONFIG_OPTION_SVG
/**************************************************************************
*
* Error Strings

View File

@ -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
@ -1206,6 +1207,9 @@ FT_BEGIN_HEADER
* altered with @FT_Set_MM_Design_Coordinates,
* @FT_Set_Var_Design_Coordinates, or @FT_Set_Var_Blend_Coordinates.
* This flag is unset by a call to @FT_Set_Named_Instance.
*
* FT_FACE_FLAG_SVG ::
* Set if the current face has an SVG table.
*/
#define FT_FACE_FLAG_SCALABLE ( 1L << 0 )
#define FT_FACE_FLAG_FIXED_SIZES ( 1L << 1 )
@ -1223,6 +1227,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 )
/**************************************************************************

View File

@ -223,6 +223,76 @@ FT_BEGIN_HEADER
} FT_OutlineGlyphRec;
/**************************************************************************
*
* @type:
* FT_SvgGlyph
*
* @description:
* A handle to an object used to model an SVG glyph image. This is a
* sub-class of @FT_Glyph, and a pointer to @FT_SvgGlyphRec.
*/
typedef struct FT_SvgGlyphRec_* FT_SvgGlyph;
/**************************************************************************
*
* @struct:
* FT_SvgGlyphRec
*
* @description:
* A structure used for SVG glyph images. This really is a 'sub-class'
* of @FT_OutlineGlyphRec.
*
* @fields:
* root ::
* The root @FT_OutlineGlyphRec fields.
*
* svg_document ::
* A pointer to the SVG document.
*
* svg_document_length ::
* The length of the svg_document.
*
* glyph_index ::
* The index of the glyph to be rendered.
*
* metrics ::
* A metrics object storing the size information.
*
* units_per_EM ::
* The size of the EM square.
*
* start_glyph_id ::
* The starting glyph ID for the glyph range that this document has.
*
* end_glyph_id ::
* The ending glyph ID for the glyph range that this document has.
*
* @note:
* `metrics` and `units_per_EM` might look like repetitions since both
* fields are stored in face objects. However, the Glyph Management API
* requires an `FT_Glyph` to store all the information that completely
* describes a glyph. Outline glyphs are themselves scaled thus they
* don't need this information. However, SVG documents do. The field of
* `units_per_EM` is needed because the SVG is to be scaled in case its
* viewbox size differs from `units_per_EM`. For more info, refer to
* the section _Coordinate Systems and Glyph Metrics_ of the OpenType
* SVG specs.
*/
typedef struct FT_SvgGlyphRec_
{
FT_OutlineGlyphRec root;
FT_Byte* svg_document;
FT_ULong svg_document_length;
FT_UInt glyph_index;
FT_Size_Metrics metrics;
FT_UShort units_per_EM;
FT_UShort start_glyph_id;
FT_UShort end_glyph_id;
/* TODO: (OT-SVG) Maybe put a transformation matrix here */
} FT_SvgGlyphRec;
/**************************************************************************
*
* @function:

View File

@ -732,6 +732,10 @@ FT_BEGIN_HEADER
* contours. Some Type~1 fonts, like those in the Hershey family,
* contain glyphs in this format. These are described as @FT_Outline,
* but FreeType isn't currently capable of rendering them correctly.
*
* FT_GLYPH_FORMAT_SVG ::
* The glyph is represented by an SVG documents in the SVG table.
*
*/
typedef enum FT_Glyph_Format_
{
@ -740,7 +744,8 @@ FT_BEGIN_HEADER
FT_IMAGE_TAG( FT_GLYPH_FORMAT_COMPOSITE, 'c', 'o', 'm', 'p' ),
FT_IMAGE_TAG( FT_GLYPH_FORMAT_BITMAP, 'b', 'i', 't', 's' ),
FT_IMAGE_TAG( FT_GLYPH_FORMAT_OUTLINE, 'o', 'u', 't', 'l' ),
FT_IMAGE_TAG( FT_GLYPH_FORMAT_PLOTTER, 'p', 'l', 'o', 't' )
FT_IMAGE_TAG( FT_GLYPH_FORMAT_PLOTTER, 'p', 'l', 'o', 't' ),
FT_IMAGE_TAG( FT_GLYPH_FORMAT_SVG, 's', 'v', 'g', ' ' )
} FT_Glyph_Format;
@ -752,6 +757,7 @@ FT_BEGIN_HEADER
#define ft_glyph_format_bitmap FT_GLYPH_FORMAT_BITMAP
#define ft_glyph_format_outline FT_GLYPH_FORMAT_OUTLINE
#define ft_glyph_format_plotter FT_GLYPH_FORMAT_PLOTTER
#define ft_glyph_format_svg FT_GLYPH_FORMAT_SVG
/*************************************************************************/

View File

@ -418,7 +418,8 @@ FT_BEGIN_HEADER
* initializing the glyph slot.
*/
#define FT_GLYPH_OWN_BITMAP 0x1U
#define FT_GLYPH_OWN_BITMAP 0x1U
#define FT_GLYPH_OWN_GZIP_SVG 0x2U
typedef struct FT_Slot_InternalRec_
{
@ -889,6 +890,10 @@ FT_BEGIN_HEADER
* created. @FT_Reference_Library increments this counter, and
* @FT_Done_Library only destroys a library if the counter is~1,
* otherwise it simply decrements it.
*
* svg_renderer_state ::
* A pointer to a state object that will have the state of the SVG
* Renderer. This will be totally managed by the renderer.
*/
typedef struct FT_LibraryRec_
{
@ -916,6 +921,9 @@ FT_BEGIN_HEADER
FT_Int refcount;
#ifdef FT_CONFIG_OPTION_SVG
void* svg_renderer_state;
#endif
} FT_LibraryRec;

View File

@ -312,6 +312,31 @@ FT_BEGIN_HEADER
TT_SBit_MetricsRec *ametrics );
/**************************************************************************
*
* @functype:
* TT_Load_Svg_Doc_Func
*
* @description:
* Scans the SVG documents list to find the document containing the glyph
* that has the id "glyph<glyph_index>".
*
* @input:
* glyph ::
* The glyph slot from which pointers to SVG documents list will be
* grabbed. The results will be stored back in the slot too.
*
* glyph_index ::
* The index of the glyph that is to be looked up.
*
* @return:
* FreeType error code. 0 means success.
*/
typedef FT_Error
(*TT_Load_Svg_Doc_Func)( FT_GlyphSlot glyph,
FT_UInt glyph_index );
/**************************************************************************
*
* @functype:
@ -778,6 +803,10 @@ FT_BEGIN_HEADER
TT_Get_Name_Func get_name;
TT_Get_Name_ID_Func get_name_id;
/* Open Type SVG Support */
TT_Load_Table_Func load_svg;
TT_Free_Table_Func free_svg;
TT_Load_Svg_Doc_Func load_svg_doc;
} SFNT_Interface;
@ -824,7 +853,10 @@ FT_BEGIN_HEADER
colr_blend_, \
get_metrics_, \
get_name_, \
get_name_id_ ) \
get_name_id_, \
load_svg_, \
free_svg_, \
load_svg_doc_ ) \
static const SFNT_Interface class_ = \
{ \
goto_table_, \
@ -864,7 +896,10 @@ FT_BEGIN_HEADER
colr_blend_, \
get_metrics_, \
get_name_, \
get_name_id_ \
get_name_id_, \
load_svg_, \
free_svg_, \
load_svg_doc_ \
};

View File

@ -1645,6 +1645,8 @@ FT_BEGIN_HEADER
void* cpal;
void* colr;
/* OpenType SVG Glyph Support */
void* svg;
} TT_FaceRec;

View File

@ -0,0 +1,196 @@
/****************************************************************************
*
* svgrenderer.h
*
* Interface for SVG Renderer Module (specification).
*
* Copyright (C) 2004-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 FTSVG_RENDERER_H_
#define FTSVG_RENDERER_H_
#include <ft2build.h>
#include FT_FREETYPE_H
#ifdef FREETYPE_H
#error "freetype.h of FreeType 1 has been loaded!"
#error "Please fix the directory search order for header files"
#error "so that freetype.h of FreeType 2 is found first."
#endif
FT_BEGIN_HEADER
/**************************************************************************
*
* @functype:
* SVG_Lib_Init_Func
*
* @description:
* A callback used to initiate the SVG Rendering port
*
* @input:
* library ::
* A instance of library. This is required to initialize the
* renderer's state which will be held in the library.
*
* @return:
* FreeType error code. 0 means success.
*/
typedef FT_Error
(*SVG_Lib_Init_Func)( FT_Library library );
/**************************************************************************
*
* @functype:
* SVG_Lib_Free_Func
*
* @description:
* A callback used to free the SVG Rendering port. Calling this callback
* shall do all cleanups that the SVG Rendering port wants to do.
*
* @input:
* library ::
* A instance of library. This is required to free the renderer's
* state which will be held in the library.
*/
typedef void
(*SVG_Lib_Free_Func)( FT_Library library );
/**************************************************************************
*
* @functype:
* SVG_Lib_Render_Func
*
* @description:
* A callback used to render the glyph loaded in the slot.
*
* @input:
* slot ::
* The whole glyph slot object.
*
* outline_bbox ::
* The bounding box of the glyph in font units. So that the renderer
* may not need to calculate it again.
*
* @return:
* FreeType error code. 0 means success.
*/
typedef FT_Error
(*SVG_Lib_Render_Func)( FT_GlyphSlot slot,
FT_BBox outline_bbox);
/**************************************************************************
*
* @functype:
* SVG_Lib_Get_Buffer_Size_Func
*
* @description:
* A callback which is called to get the size of the image buffer needed.
* This buffer will ultimately be populated by `SVG_Lib_Render_Func`
* hook.
*
* @input:
* slot ::
* The glyph slot which has the SVG document loaded as well as other
* info.
*
* bbox ::
* The bbox in font units. This is required for the rendering port to
* predict the final size of the image buffer.
*
* @return:
* Size of the state structure in bytes.
*/
typedef FT_ULong
(*SVG_Lib_Get_Buffer_Size_Func)( FT_GlyphSlot slot,
FT_BBox bbox );
typedef struct SVG_RendererHooks_
{
/* Api Hooks for OT-SVG Rendering */
SVG_Lib_Init_Func init_svg;
SVG_Lib_Free_Func free_svg;
SVG_Lib_Render_Func render_svg;
SVG_Lib_Get_Buffer_Size_Func get_buffer_size;
} SVG_RendererHooks;
/**************************************************************************
*
* @struct:
* FT_SVG_DocumentRec_
*
* @description:
* A structure that models one SVG document.
*
* @fields:
* svg_document ::
* A pointer to the SVG document string.
*
* svg_document_length ::
* The length of the SVG document string.
*
* metrics ::
* A metrics object storing the size information.
*
* units_per_EM ::
* The size of the EM square.
*
* start_glyph_id ::
* The starting glyph ID for the glyph range that this document has.
*
* end_glyph_id ::
* The ending glyph ID for the glyph range that this document has.
*
* @note:
* `metrics` and `units_per_EM` might look like repetitions since both
* fields are stored in face objects. However, the Glyph Management API
* requires an `FT_Glyph` to store all the information that completely
* describes a glyph. Outline glyphs are themselves scaled thus they
* don`t need this information. However, SVG documents do. The field
* of `units_per_EM` is needed because the SVG is to be scaled in case
* its viewbox size differs from `units_per_EM`. For more info, refer
* to the section `Coordinate Systems and Glyph Metrics` of the OpenType
* SVG specs.
*/
typedef struct FT_SVG_DocumentRec_
{
FT_Byte* svg_document;
FT_ULong svg_document_length;
FT_Size_Metrics metrics;
FT_UShort units_per_EM;
FT_UShort start_glyph_id;
FT_UShort end_glyph_id;
/* TODO: (OT-SVG) Not storing glyph_index here for now. Might need to
* at some point. Review this! */
} FT_SVG_DocumentRec;
/**************************************************************************
*
* @type:
* FT_SVG_Document
*
* @description:
* A handle to a FT_SVG_DocumentRec object.
*/
typedef struct FT_SVG_DocumentRec_* FT_SVG_Document;
FT_END_HEADER
#endif

View File

@ -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', ' ' )

View File

@ -99,6 +99,9 @@ RASTER_MODULES += raster
# Anti-aliasing rasterizer.
RASTER_MODULES += smooth
# OT-SVG
RASTER_MODULES += svg
####
#### auxiliary modules

View File

@ -35,6 +35,7 @@
#include FT_OUTLINE_H
#include FT_BITMAP_H
#include FT_INTERNAL_OBJECTS_H
#include FT_SVG_RENDER_H
/**************************************************************************
@ -275,6 +276,173 @@
ft_outline_glyph_prepare /* FT_Glyph_PrepareFunc glyph_prepare */
)
#ifdef FT_CONFIG_OPTION_SVG
/*************************************************************************/
/*************************************************************************/
/**** ****/
/**** FT_SvgGlyph support ****/
/**** ****/
/*************************************************************************/
/*************************************************************************/
FT_CALLBACK_DEF( FT_Error )
ft_svg_glyph_init( FT_Glyph svg_glyph,
FT_GlyphSlot slot )
{
FT_ULong doc_length;
FT_SVG_Document document;
FT_SvgGlyph glyph = (FT_SvgGlyph)svg_glyph;
FT_Error error = FT_Err_Ok;
FT_Memory memory = FT_GLYPH( glyph )->library->memory;
if ( slot->format != FT_GLYPH_FORMAT_SVG )
{
error = FT_THROW( Invalid_Glyph_Format );
goto Exit;
}
if ( slot->other == NULL )
{
error = FT_THROW( Invalid_Slot_Handle );
goto Exit;
}
document = (FT_SVG_Document)slot->other;
if ( document->svg_document_length == 0 )
{
error = FT_THROW( Invalid_Slot_Handle );
goto Exit;
}
/* init the parent first */
slot->format = FT_GLYPH_FORMAT_OUTLINE;
ft_outline_glyph_class.glyph_init( svg_glyph, slot );
slot->format = FT_GLYPH_FORMAT_SVG;
/* allocate a new document */
doc_length = document->svg_document_length;
glyph->svg_document = memory->alloc( memory, doc_length );
glyph->svg_document_length = doc_length;
glyph->glyph_index = slot->glyph_index;
glyph->metrics = document->metrics;
glyph->units_per_EM = document->units_per_EM;
glyph->start_glyph_id = document->start_glyph_id;
glyph->end_glyph_id = document->end_glyph_id;
/* copy the document into glyph */
FT_MEM_COPY( glyph->svg_document, document->svg_document, doc_length );
Exit:
return error;
}
FT_CALLBACK_DEF( void )
ft_svg_glyph_done( FT_Glyph svg_glyph )
{
FT_SvgGlyph glyph = (FT_SvgGlyph)svg_glyph;
FT_Memory memory = svg_glyph->library->memory;
/* free the parent first */
ft_outline_glyph_class.glyph_done( svg_glyph );
/* just free the memory */
memory->free( memory, glyph->svg_document );
}
FT_CALLBACK_DEF( FT_Error )
ft_svg_glyph_copy( FT_Glyph svg_source,
FT_Glyph svg_target )
{
FT_SvgGlyph source = (FT_SvgGlyph)svg_source;
FT_SvgGlyph target = (FT_SvgGlyph)svg_target;
FT_Error error = FT_Err_Ok;
FT_Memory memory = FT_GLYPH( source )->library->memory;
if ( svg_source->format != FT_GLYPH_FORMAT_SVG )
{
error = FT_THROW( Invalid_Glyph_Format );
return error;
}
if ( source->svg_document_length == 0 )
{
error = FT_THROW( Invalid_Slot_Handle );
return error;
}
/* copy the parent first */
ft_outline_glyph_class.glyph_copy( svg_source, svg_target );
target->glyph_index = source->glyph_index;
target->svg_document_length = source->svg_document_length;
target->metrics = source->metrics;
target->units_per_EM = source->units_per_EM;
target->start_glyph_id = source->start_glyph_id;
target->end_glyph_id = source->end_glyph_id;
/* allocate space for the svg document */
target->svg_document = memory->alloc( memory,
target->svg_document_length );
/* copy the stuff */
FT_MEM_COPY( target->svg_document,
source->svg_document,
target->svg_document_length );
return error;
}
FT_CALLBACK_DEF( FT_Error )
ft_svg_glyph_prepare( FT_Glyph svg_glyph,
FT_GlyphSlot slot )
{
FT_SvgGlyph glyph = (FT_SvgGlyph)svg_glyph;
FT_Error error = FT_Err_Ok;
FT_Memory memory = svg_glyph->library->memory;
FT_SVG_Document document;
/* TODO: (OT-SVG) this probably creates a memory leak. Fix it */
if ( FT_NEW( document ) )
return error;
/* call the parent and prepare it */
ft_outline_glyph_class.glyph_prepare( svg_glyph, slot );
slot->format = FT_GLYPH_FORMAT_SVG;
document->svg_document = glyph->svg_document;
document->svg_document_length = glyph->svg_document_length;
document->metrics = glyph->metrics;
document->units_per_EM = glyph->units_per_EM;
document->start_glyph_id = glyph->start_glyph_id;
document->end_glyph_id = glyph->end_glyph_id;
slot->format = FT_GLYPH_FORMAT_SVG;
slot->glyph_index = glyph->glyph_index;
slot->other = document;
return error;
}
FT_DEFINE_GLYPH(
ft_svg_glyph_class,
sizeof ( FT_SvgGlyphRec ),
FT_GLYPH_FORMAT_SVG,
ft_svg_glyph_init, /* FT_Glyph_InitFunc glyph_init */
ft_svg_glyph_done, /* FT_Glyph_DoneFunc glyph_done */
ft_svg_glyph_copy, /* FT_Glyph_CopyFunc glyph_copy */
NULL, /* FT_Glyph_TransformFunc glyph_transform */
NULL, /* FT_Glyph_GetBBoxFunc glyph_bbox */
ft_svg_glyph_prepare /* FT_Glyph_PrepareFunc glyph_prepare */
)
#endif
/*************************************************************************/
/*************************************************************************/
@ -376,6 +544,12 @@
else if ( format == FT_GLYPH_FORMAT_OUTLINE )
clazz = &ft_outline_glyph_class;
#ifdef FT_CONFIG_OPTION_SVG
/* if it is a SVG glyph */
else if ( format == FT_GLYPH_FORMAT_SVG )
clazz = &ft_svg_glyph_class;
#endif
else
{
/* try to find a renderer that supports the glyph image format */
@ -592,7 +766,16 @@
/* prepare dummy slot for rendering */
error = clazz->glyph_prepare( glyph, &dummy );
if ( !error )
{
error = FT_Render_Glyph_Internal( glyph->library, &dummy, render_mode );
#ifdef FT_CONFIG_OPTION_SVG
if ( clazz == &ft_svg_glyph_class )
{
FT_Memory memory = library->memory;
FT_FREE( dummy.other );
}
#endif
}
#if 1
if ( !destroy && origin )

View File

@ -40,6 +40,7 @@
#include FT_SERVICE_TT_CMAP_H
#include FT_SERVICE_KERNING_H
#include FT_SERVICE_TRUETYPE_ENGINE_H
#include FT_SVG_RENDER_H
#include FT_DRIVER_H
@ -317,6 +318,17 @@
if ( !error && clazz->init_slot )
error = clazz->init_slot( slot );
#ifdef FT_CONFIG_OPTION_SVG
/* check if SVG table exists allocate the space in slot->other */
if ( slot->face->face_flags & FT_FACE_FLAG_SVG )
{
FT_SVG_Document document;
if ( FT_NEW( document ) )
goto Exit;
slot->other = document;
}
#endif
Exit:
return error;
}
@ -551,7 +563,23 @@
slot->subglyphs = NULL;
slot->control_data = NULL;
slot->control_len = 0;
#ifndef FT_CONFIG_OPTION_SVG
slot->other = NULL;
#else
if ( !( slot->face->face_flags & FT_FACE_FLAG_SVG ) )
slot->other = NULL;
else
{
if ( slot->internal->flags & FT_GLYPH_OWN_GZIP_SVG )
{
FT_Memory memory = slot->face->memory;
FT_SVG_Document doc = (FT_SVG_Document)slot->other;
FT_FREE( doc->svg_document );
slot->internal->load_flags &= ~FT_GLYPH_OWN_GZIP_SVG;
}
}
#endif
slot->format = FT_GLYPH_FORMAT_NONE;
slot->linearHoriAdvance = 0;
@ -569,6 +597,20 @@
FT_Memory memory = driver->root.memory;
#ifdef FT_CONFIG_OPTION_SVG
if ( slot->face->face_flags & FT_FACE_FLAG_SVG )
{
/* free memory in case svg was there */
if ( slot->internal->flags & FT_GLYPH_OWN_GZIP_SVG )
{
FT_SVG_Document doc = (FT_SVG_Document)slot->other;
FT_FREE( doc->svg_document );
slot->internal->flags &= ~FT_GLYPH_OWN_GZIP_SVG;
}
FT_FREE( slot->other );
}
#endif
if ( clazz->done_slot )
clazz->done_slot( slot );
@ -587,6 +629,7 @@
FT_FREE( slot->internal );
}
}
@ -837,6 +880,14 @@
if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY )
load_flags &= ~FT_LOAD_RENDER;
#ifdef FT_CONFIG_OPTION_SVG
if ( ( load_flags & FT_LOAD_COLOR ) &&
( ttface->svg ) )
{
FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE);
}
#endif
/*
* Determine whether we need to auto-hint or not.
* The general rules are:
@ -4403,6 +4454,13 @@
render->render = clazz->render_glyph;
}
#ifdef FT_CONFIG_OPTION_SVG
if ( clazz->glyph_format == FT_GLYPH_FORMAT_SVG )
{
render->render = clazz->render_glyph;
}
#endif
/* add to list */
node->data = module;
FT_List_Add( &library->renderers, node );
@ -4538,7 +4596,6 @@
{
case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */
break;
default:
if ( slot->internal->load_flags & FT_LOAD_COLOR )
{
@ -5546,5 +5603,4 @@
return 0;
}
/* END */

View File

@ -177,7 +177,8 @@
if ( !error )
{
if ( face->glyph->format == FT_GLYPH_FORMAT_BITMAP ||
face->glyph->format == FT_GLYPH_FORMAT_OUTLINE )
face->glyph->format == FT_GLYPH_FORMAT_OUTLINE ||
face->glyph->format == FT_GLYPH_FORMAT_SVG )
{
/* ok, copy it */
FT_Glyph glyph;

View File

@ -347,6 +347,21 @@
if ( load_flags & FT_LOAD_SBITS_ONLY )
return FT_THROW( Invalid_Argument );
#ifdef FT_CONFIG_OPTION_SVG
/* check for OT-SVG */
if ( ( load_flags & FT_LOAD_COLOR ) &&
( ((TT_Face)glyph->root.face)->svg ) )
{
SFNT_Service sfnt = (SFNT_Service)((TT_Face)glyph->root.face)->sfnt;
error = sfnt->load_svg_doc( (FT_GlyphSlot)glyph, glyph_index );
if( error == FT_Err_Ok )
{
glyph->root.format = FT_GLYPH_FORMAT_SVG;
return error;
}
}
#endif
/* if we have a CID subfont, use its matrix (which has already */
/* been multiplied with the root matrix) */

View File

@ -37,6 +37,10 @@
#include "ttcpal.h"
#endif
#ifdef FT_CONFIG_OPTION_SVG
#include "ttsvg.h" /* OpenType SVG support */
#endif
#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
#include "ttpost.h"
#endif
@ -1208,6 +1212,12 @@
#define PUT_EMBEDDED_BITMAPS( 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_COLOR_LAYERS
#define PUT_COLOR_LAYERS( a ) a
#else
@ -1294,7 +1304,13 @@
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 */
PUT_SVG_SUPPORT( tt_face_load_svg_doc )
/* TT_Load_Svg_Doc_Func load_svg_doc */
)

View File

@ -27,6 +27,7 @@
#include "ttcmap.c"
#include "ttcolr.c"
#include "ttcpal.c"
#include "ttsvg.c"
#include "ttkern.c"
#include "ttload.c"

View File

@ -953,6 +953,14 @@
LOAD_( colr );
}
#ifdef FT_CONFIG_OPTION_SVG
/* opentype svg colored glyph support */
if ( sfnt->load_svg )
{
LOAD_( svg );
}
#endif
/* consider the pclt, kerning, and gasp tables as optional */
LOAD_( pclt );
LOAD_( gasp );
@ -1372,6 +1380,11 @@
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

260
src/sfnt/ttsvg.c Normal file
View File

@ -0,0 +1,260 @@
/****************************************************************************
*
* 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 <ft2build.h>
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_OBJECTS_H
#include FT_TRUETYPE_TAGS_H
#include FT_GZIP_H
#include FT_SVG_RENDER_H
#ifdef FT_CONFIG_OPTION_SVG
#include "ttsvg.h"
/* TODO: (OT-SVG) Decide whether to add documentation here or not */
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;
/* Memory that backs up SVG */
void* table;
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 );
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 );
}
}
FT_Error
find_doc( FT_Byte* stream,
FT_UShort num_entries,
FT_UInt glyph_index,
FT_ULong *doc_offset,
FT_ULong *doc_length,
FT_UShort *start_glyph,
FT_UShort *end_glyph )
{
FT_Error error;
FT_UShort start_glyph_id;
FT_UShort end_glyph_id;
FT_ULong cur_doc_offset;
FT_ULong cur_doc_length;
FT_Bool found = FALSE;
FT_UInt i = 0;
/* TODO: (OT-SVG) Convert to efficient search algorithm */
/* TODO: (OT-SVG) Use Frame Fields here instead of `FT_NEXT_*' */
for ( i = 0; i < num_entries; i++)
{
start_glyph_id = FT_NEXT_USHORT( stream );
end_glyph_id = FT_NEXT_USHORT( stream );
cur_doc_offset = FT_NEXT_ULONG( stream );
cur_doc_length = FT_NEXT_ULONG( stream );
if ( ( glyph_index >= start_glyph_id) &&
( glyph_index <= end_glyph_id ) )
{
found = TRUE;
*doc_offset = cur_doc_offset;
*doc_length = cur_doc_length;
break;
}
}
if ( found != TRUE )
error = FT_THROW( Invalid_Glyph_Index );
else
{
*start_glyph = start_glyph_id;
*end_glyph = end_glyph_id;
error = FT_Err_Ok;
}
return error;
}
FT_LOCAL_DEF(FT_Error)
tt_face_load_svg_doc( FT_GlyphSlot glyph,
FT_UInt glyph_index )
{
/* TODO: (OT-SVG) properly clean stuff here on errors */
FT_Byte* doc_list; /* Pointer to the Svg Document List */
FT_UShort num_entries; /* Total no of entires in doc list */
FT_ULong doc_offset;
FT_ULong doc_length;
FT_UShort start_glyph_id;
FT_UShort end_glyph_id;
FT_ULong uncomp_size;
FT_Byte* uncomp_buffer;
FT_Error error = FT_Err_Ok;
TT_Face face = (TT_Face)glyph->face;
FT_Memory memory = face->root.memory;
Svg* svg = face->svg;
FT_SVG_Document svg_document = glyph->other;
/* handle svg being 0x0 situation here */
doc_list = svg->svg_doc_list;
num_entries = FT_NEXT_USHORT( doc_list );
error = find_doc( doc_list, num_entries, glyph_index,
&doc_offset, &doc_length,
&start_glyph_id, &end_glyph_id );
if ( error != FT_Err_Ok )
return error;
doc_list = svg->svg_doc_list; /* Reset to so we can use it again */
doc_list = (FT_Byte*)( doc_list + doc_offset );
if( ( doc_list[0] == 0x1F ) && ( doc_list[1] == 0x8B )
&& ( doc_list[2] == 0x08 ) )
{
/* get the size of the orignal document. This helps in alotting the
* buffer to accomodate the uncompressed version. The last 4 bytes
* of the compressed document are equal to orignal_size modulo 2^32.
* Since SVG docs will be lesser in size then 2^32, we can use this
* accurately. The four bytes are stored in little-endian format.
*/
uncomp_size = (FT_ULong)doc_list[doc_length - 1] << 24 |
(FT_ULong)doc_list[doc_length - 2] << 16 |
(FT_ULong)doc_list[doc_length - 3] << 8 |
(FT_ULong)doc_list[doc_length - 4];
uncomp_buffer = (FT_Byte*) memory->alloc(memory, uncomp_size);
glyph->internal->flags |= FT_GLYPH_OWN_GZIP_SVG;
error = FT_Gzip_Uncompress( memory, uncomp_buffer, &uncomp_size,
doc_list, doc_length );
if ( error != FT_Err_Ok )
{
error = FT_THROW( Invalid_Table );
return error;
}
doc_list = uncomp_buffer;
doc_length = uncomp_size;
}
svg_document->svg_document = doc_list;
svg_document->svg_document_length = doc_length;
svg_document->metrics = glyph->face->size->metrics;
svg_document->units_per_EM = glyph->face->units_per_EM;
svg_document->start_glyph_id = start_glyph_id;
svg_document->end_glyph_id = end_glyph_id;
glyph->other = svg_document;
glyph->metrics.horiAdvance *= ((float)glyph->face->size->metrics.x_ppem)/
((float)glyph->face->units_per_EM) * 64.0;
glyph->metrics.vertAdvance *= ((float)glyph->face->size->metrics.y_ppem)/
((float)glyph->face->units_per_EM) * 64.0;
return FT_Err_Ok;
}
#else /* !FT_CONFIG_OPTION_SVG */
/* ANSI C doesn't like empty source files */
typedef int _tt_cpal_dummy;
#endif /* !FT_CONFIG_OPTION_SVG */

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

@ -0,0 +1,39 @@
/****************************************************************************
*
* 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 <ft2build.h>
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_LOCAL(FT_Error)
tt_face_load_svg_doc( FT_GlyphSlot glyph,
FT_UInt glyph_index );
FT_END_HEADER
#endif /* __TTSVG_H__ */
/* END */

167
src/svg/ftsvg.c Normal file
View File

@ -0,0 +1,167 @@
/****************************************************************************
*
* ftsvg.c
*
* The FreeType svg renderer interface (body).
*
* Copyright (C) 1996-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.
*
*/
#include <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_SERVICE_PROPERTIES_H
#include FT_SVG_RENDER_H
#include FT_BBOX_H
#include <stdio.h>
#include "ftsvg.h"
/* ft_svg_init */
static FT_Error
ft_svg_init( SVG_Renderer svg_module )
{
FT_Error error = FT_Err_Ok;
svg_module->loaded = FALSE;
return error;
}
static void
ft_svg_done( SVG_Renderer svg_module )
{
FT_Library library = svg_module->root.root.library;
if ( svg_module->loaded == TRUE )
svg_module->hooks.free_svg( library );
svg_module->loaded = FALSE;
}
static FT_Error
ft_svg_render( FT_Renderer renderer,
FT_GlyphSlot slot,
FT_Render_Mode mode,
const FT_Vector* origin )
{
SVG_Renderer svg_renderer = (SVG_Renderer)renderer;
FT_Library library = renderer->root.library;
FT_Memory memory = library->memory;
FT_BBox outline_bbox;
FT_Error error;
FT_ULong size_image_buffer;
SVG_RendererHooks hooks = svg_renderer->hooks;
if ( svg_renderer->loaded == FALSE )
{
error = hooks.init_svg( library );
svg_renderer->loaded = TRUE;
}
/* Let's calculate the bounding box in font units here */
error = FT_Outline_Get_BBox( &slot->outline, &outline_bbox );
if( error != FT_Err_Ok )
return error;
size_image_buffer = hooks.get_buffer_size( slot, outline_bbox );
FT_MEM_ALLOC( slot->bitmap.buffer, size_image_buffer );
if ( error )
return error;
return hooks.render_svg( slot, outline_bbox );
}
static FT_Error
ft_svg_property_set( FT_Module module,
const char* property_name,
const void* value,
FT_Bool value_is_string )
{
FT_Error error = FT_Err_Ok;
SVG_Renderer renderer = (SVG_Renderer)module;
if ( !ft_strcmp( property_name, "svg_hooks" ) )
{
SVG_RendererHooks* hooks = (SVG_RendererHooks*)value;
renderer->hooks = *hooks;
}
else
{
error = FT_THROW( Missing_Property );
}
return error;
}
static FT_Error
ft_svg_property_get( FT_Module module,
const char* property_name,
const void* value )
{
FT_Error error = FT_Err_Ok;
SVG_Renderer renderer = (SVG_Renderer)module;
if ( !ft_strcmp( property_name, "svg_hooks" ) )
{
SVG_RendererHooks* hooks = (SVG_RendererHooks*)value;
*hooks = renderer->hooks;
}
else
{
error = FT_THROW( Missing_Property );
}
return error;
}
FT_DEFINE_SERVICE_PROPERTIESREC(
ft_svg_service_properties,
(FT_Properties_SetFunc)ft_svg_property_set, /* set_property */
(FT_Properties_GetFunc)ft_svg_property_get /* get_property */
)
FT_DEFINE_SERVICEDESCREC1(
ft_svg_services,
FT_SERVICE_ID_PROPERTIES, &ft_svg_service_properties )
FT_CALLBACK_DEF( FT_Module_Interface )
ft_svg_get_interface( FT_Module module,
const char* ft_svg_interface )
{
FT_Module_Interface result;
result = ft_service_list_lookup( ft_svg_services, ft_svg_interface );
if ( result )
return result;
return 0;
}
FT_DEFINE_RENDERER(
ft_svg_renderer_class,
FT_MODULE_RENDERER,
sizeof( SVG_RendererRec ),
"ot-svg",
0x10000L,
0x20000L,
NULL, /* module specific interface */
(FT_Module_Constructor)ft_svg_init, /* module_init */
(FT_Module_Destructor)ft_svg_done, /* module_done */
ft_svg_get_interface, /* get_interface */
FT_GLYPH_FORMAT_SVG,
(FT_Renderer_RenderFunc)ft_svg_render,
NULL,
NULL,
NULL,
NULL
)

32
src/svg/ftsvg.h Normal file
View File

@ -0,0 +1,32 @@
/****************************************************************************
*
* ftsvg.h
*
* The FreeType svg renderer interface (specification).
*
* Copyright (C) 1996-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 FTSVG_H_
#define FTSVG_H_
#include <ft2build.h>
#include FT_RENDER_H
FT_BEGIN_HEADER
FT_DECLARE_RENDERER( ft_svg_renderer_class )
FT_END_HEADER
#endif /* FTSVG_H_ */
/* END */

23
src/svg/module.mk Normal file
View File

@ -0,0 +1,23 @@
#
# FreeType 2 svg renderer module definition
#
# Copyright (C) 1996-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.
FTMODULE_H_COMMANDS += SVG_MODULE
define SVG_MODULE
$(OPEN_DRIVER) FT_Renderer_Class, ft_svg_renderer_class $(CLOSE_DRIVER)
$(ECHO_DRIVER)svg $(ECHO_DRIVER_DESC)svg renderer module$(ECHO_DRIVER_DONE)
endef
# EOF

72
src/svg/rules.mk Normal file
View File

@ -0,0 +1,72 @@
#
# FreeType 2 svg renderer module build rules
#
# Copyright (C) 1996-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 renderer driver directory
#
SVG_DIR := $(SRC_DIR)/svg
# compilation flags for the driver
#
SVG_COMPILE := $(CC) $(ANSIFLAGS) \
$I$(subst /,$(COMPILER_SEP),$(SVG_DIR)) \
$(INCLUDE_FLAGS) \
$(FT_CFLAGS)
# raster driver sources (i.e., C files)
#
SVG_DRV_SRC := $(SVG_DIR)/ftsvg.c \
$(SVG_DIR)/svgtypes.c
# raster driver headers
#
SVG_DRV_H := $(SVG_DIR)/ftsvg.h
# raster driver object(s)
#
# RASTER_DRV_OBJ_M is used during `multi' builds.
# RASTER_DRV_OBJ_S is used during `single' builds.
#
#RASTER_DRV_OBJ_M := $(RASTER_DRV_SRC:$(RASTER_DIR)/%.c=$(OBJ_DIR)/%.$O)
SVG_DRV_OBJ_M := $(SVG_DRV_SRC:$(SVG_DIR)/%.c=$(OBJ_DIR)/%.$O)
SVG_DRV_OBJ_S := $(OBJ_DIR)/svg.$O
# raster driver source file for single build
#
SVG_DRV_SRC_S := $(SVG_DIR)/svg.c
# raster driver - single object
#
$(SVG_DRV_OBJ_S): $(SVG_DRV_SRC_S) $(SVG_DRV_SRC) \
$(FREETYPE_H) $(SVG_DRV_H)
$(SVG_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(SVG_DRV_SRC_S))
# raster driver - multiple objects
#
$(OBJ_DIR)/%.$O: $(SVG_DIR)/%.c $(FREETYPE_H) $(SVG_DRV_H)
$(SVG_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
# update main driver object lists
#
DRV_OBJS_S += $(SVG_DRV_OBJ_S)
DRV_OBJS_M += $(SVG_DRV_OBJ_M)
# EOF

25
src/svg/svg.c Normal file
View File

@ -0,0 +1,25 @@
/****************************************************************************
*
* svg.c
*
* FreeType svg renderer module component (body only).
*
* Copyright (C) 1996-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.
*
*/
#define FT_MAKE_OPTION_SINGLE_OBJECT
#include <ft2build.h>
#include "svgtypes.c"
#include "ftsvg.c"
/* END */

32
src/svg/svgtypes.c Normal file
View File

@ -0,0 +1,32 @@
/****************************************************************************
*
* svgtypes.h
*
* TODO:
* The FreeType svg renderer internal types (specification).
*
* Copyright (C) 1996-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.
*
*/
#include <ft2build.h>
#include FT_INTERNAL_OBJECTS_H
#include FT_RENDER_H
#include FT_SVG_RENDER_H
typedef struct SVG_RendererRec_
{
FT_RendererRec root; /* This inherits FT_RendererRec */
FT_Bool loaded;
SVG_RendererHooks hooks; /* Holds out hooks to the outside library */
} SVG_RendererRec;
typedef struct SVG_RendererRec_* SVG_Renderer;

View File

@ -2892,6 +2892,21 @@
goto Exit;
}
#ifdef FT_CONFIG_OPTION_SVG
/* check for OT-SVG */
if ( ( load_flags & FT_LOAD_COLOR ) && ( ((TT_Face)glyph->face)->svg ) )
{
SFNT_Service sfnt;
sfnt = (SFNT_Service)((TT_Face)glyph->face)->sfnt;
error = sfnt->load_svg_doc( glyph, glyph_index );
if( error == FT_Err_Ok )
{
glyph->format = FT_GLYPH_FORMAT_SVG;
return error;
}
}
#endif
if ( load_flags & FT_LOAD_SBITS_ONLY )
{
error = FT_THROW( Invalid_Argument );