Compare commits
37 Commits
master
...
hooks-via-
Author | SHA1 | Date |
---|---|---|
![]() |
f40ef225a2 | |
![]() |
d94f52b0c6 | |
![]() |
02b14b7824 | |
![]() |
def48796f4 | |
![]() |
41a1572f33 | |
![]() |
6e05128713 | |
![]() |
e11721ee02 | |
![]() |
509ae10ca5 | |
![]() |
9ff1a33826 | |
![]() |
2e9e84193d | |
![]() |
b85698d447 | |
![]() |
f9b0bb6b95 | |
![]() |
11f3c827b8 | |
![]() |
5f2dcadbf2 | |
![]() |
c9308ac171 | |
![]() |
8f36343498 | |
![]() |
f70f02cdd1 | |
![]() |
72eb3b3a9d | |
![]() |
aec7ec2a62 | |
![]() |
71a8aaa807 | |
![]() |
4288f4a70a | |
![]() |
2a9f8aea1f | |
![]() |
7e3c438166 | |
![]() |
1b494f52fb | |
![]() |
204329b18e | |
![]() |
a4f1da1572 | |
![]() |
e676c86e92 | |
![]() |
5381d51956 | |
![]() |
3560126a3a | |
![]() |
8f256de2d8 | |
![]() |
7915e5e102 | |
![]() |
1ab8251ff1 | |
![]() |
68d1cab0e1 | |
![]() |
7b9673dd01 | |
![]() |
3201792dba | |
![]() |
f61fa9934f | |
![]() |
77726abc41 |
|
@ -1,3 +1,4 @@
|
|||
config.mk
|
||||
objs/vc2010/
|
||||
build
|
||||
tags
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 )
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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_ \
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1645,6 +1645,8 @@ FT_BEGIN_HEADER
|
|||
void* cpal;
|
||||
void* colr;
|
||||
|
||||
/* OpenType SVG Glyph Support */
|
||||
void* svg;
|
||||
} TT_FaceRec;
|
||||
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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', ' ' )
|
||||
|
|
|
@ -99,6 +99,9 @@ RASTER_MODULES += raster
|
|||
# Anti-aliasing rasterizer.
|
||||
RASTER_MODULES += smooth
|
||||
|
||||
# OT-SVG
|
||||
RASTER_MODULES += svg
|
||||
|
||||
|
||||
####
|
||||
#### auxiliary modules
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "ttcmap.c"
|
||||
#include "ttcolr.c"
|
||||
#include "ttcpal.c"
|
||||
#include "ttsvg.c"
|
||||
|
||||
#include "ttkern.c"
|
||||
#include "ttload.c"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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
|
||||
)
|
|
@ -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 */
|
|
@ -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
|
|
@ -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
|
|
@ -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 */
|
|
@ -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;
|
||||
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in New Issue