Add 'svg' module for OT-SVG rendering.
* CMakeLists.txt (BASE_SRCS): Add svg module file. * meson.build (ft2_public_headers): Add `otsvg.h`. * modules.cfg (RASTER_MODULES): Add `svg` module. * builds/meson/parse_modules_cfg.py: Add svg module. * include/freetype/config/ftmodule.h: Add `ft_svg_renderer_class`. * include/freetype/fterrdef.h: Add `Invalid_SVG_Document` and `Missing_SVG_Hooks` error codes. * include/freetype/internal/fttrace.h: Add tracing for `otsvg`. * include/freetype/internal/svginterface.h: New file. It adds an interface to enable the presetting hook from the `base` module. * include/freetype/otsvg.h (SVG_Lib_Init_Func, SVG_Lib_Free_Func, SVG_Lib_Render_Func, SVG_Lib_Preset_Slot_Func): New hooks for SVG rendering. (SVG_RendererHooks): New structure to access them. * src/base/ftobjs.c: Include `svginterface.h`. (ft_glyphslot_preset_bitmap): Add code for presetting the slot for SVG glyphs. (ft_add_renderer): Updated. * src/svg/*: New files.
This commit is contained in:
parent
97c09a803e
commit
0bf49bd229
|
@ -400,6 +400,7 @@ set(BASE_SRCS
|
|||
src/sdf/sdf.c
|
||||
src/sfnt/sfnt.c
|
||||
src/smooth/smooth.c
|
||||
src/svg/svg.c
|
||||
src/truetype/truetype.c
|
||||
src/type1/type1.c
|
||||
src/type42/type42.c
|
||||
|
|
|
@ -87,6 +87,7 @@ def generate_ftmodule(lists):
|
|||
name = {
|
||||
"raster": "ft_raster1",
|
||||
"smooth": "ft_smooth",
|
||||
"svg": "ft_svg",
|
||||
}.get(module)
|
||||
result += (
|
||||
"FT_USE_MODULE( FT_Renderer_Class, %s_renderer_class )\n" % name
|
||||
|
|
|
@ -28,5 +28,6 @@ FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
|
|||
FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class )
|
||||
FT_USE_MODULE( FT_Renderer_Class, ft_sdf_renderer_class )
|
||||
FT_USE_MODULE( FT_Renderer_Class, ft_bitmap_sdf_renderer_class )
|
||||
FT_USE_MODULE( FT_Renderer_Class, ft_svg_renderer_class )
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -101,6 +101,8 @@
|
|||
"too many hints" )
|
||||
FT_ERRORDEF_( Invalid_Pixel_Size, 0x17,
|
||||
"invalid pixel size" )
|
||||
FT_ERRORDEF_( Invalid_SVG_Document, 0x18,
|
||||
"invalid SVG document" )
|
||||
|
||||
/* handle errors */
|
||||
|
||||
|
@ -234,6 +236,8 @@
|
|||
"found FDEF or IDEF opcode in glyf bytecode" )
|
||||
FT_ERRORDEF_( Missing_Bitmap, 0x9D,
|
||||
"missing bitmap in strike" )
|
||||
FT_ERRORDEF_( Missing_SVG_Hooks, 0x9E,
|
||||
"SVG hooks have not been set" )
|
||||
|
||||
/* CFF, CID, and Type 1 errors */
|
||||
|
||||
|
|
|
@ -49,6 +49,9 @@ FT_TRACE_DEF( synth ) /* bold/slant synthesizer (ftsynth.c) */
|
|||
FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */
|
||||
FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */
|
||||
|
||||
/* ot-svg module */
|
||||
FT_TRACE_DEF( otsvg ) /* OT-SVG renderer (ftsvg.c) */
|
||||
|
||||
/* cache sub-system */
|
||||
FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* svginterface.h
|
||||
*
|
||||
* Interface of ot-svg module (specification only).
|
||||
*
|
||||
* Copyright (C) 2022 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 SVGINTERFACE_H_
|
||||
#define SVGINTERFACE_H_
|
||||
|
||||
#include <ft2build.h>
|
||||
#include <freetype/otsvg.h>
|
||||
|
||||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
typedef FT_Error
|
||||
(*Preset_Bitmap_Func)( FT_Module module,
|
||||
FT_GlyphSlot slot,
|
||||
FT_Bool cache );
|
||||
|
||||
typedef struct SVG_Interface_
|
||||
{
|
||||
Preset_Bitmap_Func preset_slot;
|
||||
|
||||
} SVG_Interface;
|
||||
|
||||
typedef SVG_Interface* SVG_Service;
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
#endif /* SVGINTERFACE_H_ */
|
||||
|
||||
|
||||
/* END */
|
|
@ -30,6 +30,217 @@
|
|||
|
||||
FT_BEGIN_HEADER
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @functype:
|
||||
* SVG_Lib_Init_Func
|
||||
*
|
||||
* @description:
|
||||
* A callback that is called when the first OT-SVG glyph is rendered in
|
||||
* the lifetime of an @FT_Library object. In a typical implementation,
|
||||
* one would want to allocate a structure and point the `data_pointer`
|
||||
* to it and perform any library initializations that might be needed.
|
||||
*
|
||||
* For more information on the implementation, see our standard hooks
|
||||
* based on Librsvg in the 'FreeType Demo Programs' repository.
|
||||
*
|
||||
* @inout:
|
||||
* data_pointer ::
|
||||
* The SVG rendering module stores a pointer variable that can be used
|
||||
* by clients to store any data that needs to be shared across
|
||||
* different hooks. `data_pointer` is essentially a pointer to that
|
||||
* pointer such that it can be written to as well as read from.
|
||||
*
|
||||
* @return:
|
||||
* FreeType error code. 0 means success.
|
||||
*
|
||||
* @since:
|
||||
* 2.12
|
||||
*/
|
||||
typedef FT_Error
|
||||
(*SVG_Lib_Init_Func)( FT_Pointer *data_pointer );
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @functype:
|
||||
* SVG_Lib_Free_Func
|
||||
*
|
||||
* @description:
|
||||
* A callback that is called when the `ot-svg` module is being freed.
|
||||
* It is only called if the init hook was called earlier. This means
|
||||
* that neither the init nor the free hook is called if no OT-SVG glyph
|
||||
* is rendered.
|
||||
*
|
||||
* In a typical implementation, one would want to free any state
|
||||
* structure that was allocated in the init hook and perform any
|
||||
* library-related closure that might be needed.
|
||||
*
|
||||
* For more information on the implementation, see our standard hooks
|
||||
* based on Librsvg in the 'FreeType Demo Programs' repository.
|
||||
*
|
||||
* @inout:
|
||||
* data_pointer ::
|
||||
* The SVG rendering module stores a pointer variable that can be used
|
||||
* by clients to store any data that needs to be shared across
|
||||
* different hooks. `data_pointer` is essentially a pointer to that
|
||||
* pointer such that it can be written to as well as read from.
|
||||
*
|
||||
* @since:
|
||||
* 2.12
|
||||
*/
|
||||
typedef void
|
||||
(*SVG_Lib_Free_Func)( FT_Pointer *data_pointer );
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @functype:
|
||||
* SVG_Lib_Render_Func
|
||||
*
|
||||
* @description:
|
||||
* A callback that is called to render an OT-SVG glyph. This callback
|
||||
* hook is called right after the preset hook @SVG_Lib_Preset_SlotFunc
|
||||
* has been called with `cache` set to `TRUE`. The data necessary to
|
||||
* render is available through the handle @FT_SVG_Document, which is set
|
||||
* in the `other` field of @FT_GlyphSlotRec.
|
||||
*
|
||||
* The render hook is expected to render the SVG glyph to the bitmap
|
||||
* buffer that is allocated already at `slot->bitmap.buffer`. It also
|
||||
* sets the `num_grays` value as well as `slot->format`.
|
||||
*
|
||||
* For more information on the implementation, see our standard hooks
|
||||
* based on Librsvg in the 'FreeType Demo Programs' repository.
|
||||
*
|
||||
* @input:
|
||||
* slot ::
|
||||
* The slot to render.
|
||||
*
|
||||
* @inout:
|
||||
* data_pointer ::
|
||||
* The SVG rendering module stores a pointer variable that can be used
|
||||
* by clients to store any data that needs to be shared across
|
||||
* different hooks. `data_pointer` is essentially a pointer to that
|
||||
* pointer such that it can be written to as well as read from.
|
||||
*
|
||||
* @return:
|
||||
* FreeType error code. 0 means success.
|
||||
*
|
||||
* @since:
|
||||
* 2.12
|
||||
*/
|
||||
typedef FT_Error
|
||||
(*SVG_Lib_Render_Func)( FT_GlyphSlot slot,
|
||||
FT_Pointer *data_pointer );
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @functype:
|
||||
* SVG_Lib_Preset_Slot_Func
|
||||
*
|
||||
* @description:
|
||||
* A callback that is called to preset the glyph slot. It is called from
|
||||
* two places.
|
||||
*
|
||||
* 1. When `FT_Load_Glyph` needs to preset the glyph slot.
|
||||
* 2. Right before the `svg` module calls the render callback hook.
|
||||
*
|
||||
* When it is the former, the argument `cache` is set to `FALSE`. When
|
||||
* it is the latter, the argument `cache` is set to `TRUE`. This
|
||||
* distinction has been made because many calculations that are necessary
|
||||
* for presetting a glyph slot are the same needed later for the render
|
||||
* callback hook. Thus, if `cache` is `TRUE`, the hook can _cache_ those
|
||||
* calculations in a memory block referenced by the state pointer.
|
||||
*
|
||||
* This hook is expected to preset the slot by setting parameters such as
|
||||
* `bitmap_left`, `bitmap_top`, `width`, `rows`, `pitch`, and
|
||||
* `pixel_mode`. It is also expected to set all the metrics for the slot
|
||||
* including the vertical advance if it is not already set. Typically,
|
||||
* fonts have horizontal advances but not vertical ones. If those are
|
||||
* available, they had already been set, otherwise they have to be
|
||||
* estimated and set manually. The hook must take into account the
|
||||
* transformations that have been set, and translate the transformation
|
||||
* matrices into the SVG coordinate system, as the original matrix is
|
||||
* intended for the TTF/CFF coordinate system.
|
||||
*
|
||||
* For more information on the implementation, see our standard hooks
|
||||
* based on Librsvg in the 'FreeType Demo Programs' repository.
|
||||
*
|
||||
* @input:
|
||||
* slot ::
|
||||
* The glyph slot that has the SVG document loaded.
|
||||
*
|
||||
* cache ::
|
||||
* See description.
|
||||
*
|
||||
* @inout:
|
||||
* data_pointer ::
|
||||
* The SVG rendering module stores a pointer variable that can be used
|
||||
* by clients to store any data that needs to be shared across
|
||||
* different hooks. `data_pointer` is essentially a pointer to that
|
||||
* pointer such that it can be written to as well as read from.
|
||||
*
|
||||
* @return:
|
||||
* FreeType error code. 0 means success.
|
||||
*
|
||||
* @since:
|
||||
* 2.12
|
||||
*/
|
||||
typedef FT_Error
|
||||
(*SVG_Lib_Preset_Slot_Func)( FT_GlyphSlot slot,
|
||||
FT_Bool cache,
|
||||
FT_Pointer *state );
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @struct:
|
||||
* SVG_RendererHooks
|
||||
*
|
||||
* @description:
|
||||
* A structure that stores the four hooks needed to render OT-SVG glyphs
|
||||
* properly. The structure is publicly used to set the hooks via driver
|
||||
* properties.
|
||||
*
|
||||
* The behavior of each hook is described in its documentation. One
|
||||
* thing to note is that the preset hook and the render hook often need
|
||||
* to do the same operations; therefore, it's better to cache the
|
||||
* intermediate data in a state structure to avoid calculating it twice.
|
||||
* For example, in the preset hook one can draw the glyph on a recorder
|
||||
* surface and later create a bitmap surface from it in the render hook.
|
||||
*
|
||||
* For more information on the implementation, see our standard hooks
|
||||
* based on Librsvg in the 'FreeType Demo Programs' repository.
|
||||
*
|
||||
* @fields:
|
||||
* init_svg ::
|
||||
* The initialization hook.
|
||||
*
|
||||
* free_svg ::
|
||||
* The cleanup hook.
|
||||
*
|
||||
* render_hook ::
|
||||
* The render hook.
|
||||
*
|
||||
* preset_slot ::
|
||||
* The preset hook.
|
||||
*
|
||||
* @since:
|
||||
* 2.12
|
||||
*/
|
||||
typedef struct SVG_RendererHooks_
|
||||
{
|
||||
SVG_Lib_Init_Func init_svg;
|
||||
SVG_Lib_Free_Func free_svg;
|
||||
SVG_Lib_Render_Func render_svg;
|
||||
|
||||
SVG_Lib_Preset_Slot_Func preset_slot;
|
||||
|
||||
} SVG_RendererHooks;
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* @struct:
|
||||
|
|
|
@ -172,6 +172,7 @@ ft2_public_headers = files([
|
|||
'include/freetype/fttrigon.h',
|
||||
'include/freetype/fttypes.h',
|
||||
'include/freetype/ftwinfnt.h',
|
||||
'include/freetype/otsvg.h',
|
||||
'include/freetype/t1tables.h',
|
||||
'include/freetype/ttnameid.h',
|
||||
'include/freetype/tttables.h',
|
||||
|
|
|
@ -99,6 +99,9 @@ RASTER_MODULES += smooth
|
|||
# Monochrome rasterizer.
|
||||
RASTER_MODULES += raster
|
||||
|
||||
# OT-SVG.
|
||||
RASTER_MODULES += svg
|
||||
|
||||
# Signed distance field rasterizer.
|
||||
RASTER_MODULES += sdf
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <freetype/internal/ftstream.h>
|
||||
#include <freetype/internal/sfnt.h> /* for SFNT_Load_Table_Func */
|
||||
#include <freetype/internal/psaux.h> /* for PS_Driver */
|
||||
#include <freetype/internal/svginterface.h>
|
||||
|
||||
#include <freetype/tttables.h>
|
||||
#include <freetype/tttags.h>
|
||||
|
@ -386,7 +387,18 @@
|
|||
FT_Pos width, height, pitch;
|
||||
|
||||
|
||||
if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )
|
||||
if ( slot->format == FT_GLYPH_FORMAT_SVG )
|
||||
{
|
||||
FT_Module module;
|
||||
SVG_Service svg_service;
|
||||
|
||||
|
||||
module = FT_Get_Module( slot->library, "ot-svg" );
|
||||
svg_service = (SVG_Service)module->clazz->module_interface;
|
||||
|
||||
return (FT_Bool)svg_service->preset_slot( module, slot, FALSE );
|
||||
}
|
||||
else if ( slot->format != FT_GLYPH_FORMAT_OUTLINE )
|
||||
return 1;
|
||||
|
||||
if ( origin )
|
||||
|
@ -4539,7 +4551,7 @@
|
|||
render->glyph_format = clazz->glyph_format;
|
||||
|
||||
/* allocate raster object if needed */
|
||||
if ( clazz->raster_class->raster_new )
|
||||
if ( clazz->raster_class && clazz->raster_class->raster_new )
|
||||
{
|
||||
error = clazz->raster_class->raster_new( memory, &render->raster );
|
||||
if ( error )
|
||||
|
@ -4549,6 +4561,11 @@
|
|||
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 );
|
||||
|
|
|
@ -299,7 +299,7 @@
|
|||
if ( ( doc_list[0] == 0x1F ) && ( doc_list[1] == 0x8B )
|
||||
&& ( doc_list[2] == 0x08 ) )
|
||||
{
|
||||
#ifdef FT_CONFIG_OPTION_SYSTEM_ZLIB
|
||||
#ifdef FT_CONFIG_OPTION_USE_ZLIB
|
||||
|
||||
FT_ULong uncomp_size;
|
||||
FT_Byte* uncomp_buffer;
|
||||
|
@ -339,12 +339,12 @@
|
|||
doc_list = uncomp_buffer;
|
||||
doc_length = uncomp_size;
|
||||
|
||||
#else /* !FT_CONFIG_OPTION_SYSTEM_ZLIB */
|
||||
#else /* !FT_CONFIG_OPTION_USE_ZLIB */
|
||||
|
||||
error = FT_THROW( Unimplemented_Feature );
|
||||
goto Exit;
|
||||
|
||||
#endif /* !FT_CONFIG_OPTION_SYSTEM_ZLIB */
|
||||
#endif /* !FT_CONFIG_OPTION_USE_ZLIB */
|
||||
}
|
||||
|
||||
svg_document->svg_document = doc_list;
|
||||
|
|
|
@ -0,0 +1,332 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftsvg.c
|
||||
*
|
||||
* The FreeType SVG renderer interface (body).
|
||||
*
|
||||
* Copyright (C) 2022 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 <freetype/internal/ftdebug.h>
|
||||
#include <freetype/internal/ftserv.h>
|
||||
#include <freetype/internal/services/svprop.h>
|
||||
#include <freetype/otsvg.h>
|
||||
#include <freetype/internal/svginterface.h>
|
||||
#include <freetype/ftbbox.h>
|
||||
|
||||
#include "ftsvg.h"
|
||||
#include "svgtypes.h"
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* The macro FT_COMPONENT is used in trace mode. It is an implicit
|
||||
* parameter of the FT_TRACE() and FT_ERROR() macros, usued to print/log
|
||||
* messages during execution.
|
||||
*/
|
||||
#undef FT_COMPONENT
|
||||
#define FT_COMPONENT otsvg
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_SVG
|
||||
|
||||
/* ft_svg_init */
|
||||
static FT_Error
|
||||
ft_svg_init( SVG_Renderer svg_module )
|
||||
{
|
||||
FT_Error error = FT_Err_Ok;
|
||||
|
||||
|
||||
svg_module->loaded = FALSE;
|
||||
svg_module->hooks_set = FALSE;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ft_svg_done( SVG_Renderer svg_module )
|
||||
{
|
||||
if ( svg_module->loaded == TRUE &&
|
||||
svg_module->hooks_set == TRUE )
|
||||
svg_module->hooks.free_svg( &svg_module->state );
|
||||
|
||||
svg_module->loaded = FALSE;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
ft_svg_preset_slot( FT_Module module,
|
||||
FT_GlyphSlot slot,
|
||||
FT_Bool cache )
|
||||
{
|
||||
SVG_Renderer svg_renderer = (SVG_Renderer)module;
|
||||
SVG_RendererHooks hooks = svg_renderer->hooks;
|
||||
|
||||
|
||||
if ( svg_renderer->hooks_set == FALSE )
|
||||
{
|
||||
FT_TRACE1(( "Hooks are NOT set. Can't render OT-SVG glyphs\n" ));
|
||||
return FT_THROW( Missing_SVG_Hooks );
|
||||
}
|
||||
|
||||
if ( svg_renderer->loaded == FALSE )
|
||||
{
|
||||
FT_TRACE3(( "ft_svg_preset_slot: first presetting call,"
|
||||
" calling init hook\n" ));
|
||||
hooks.init_svg( &svg_renderer->state );
|
||||
|
||||
svg_renderer->loaded = TRUE;
|
||||
}
|
||||
|
||||
return hooks.preset_slot( slot, cache, &svg_renderer->state );
|
||||
}
|
||||
|
||||
|
||||
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_Error error;
|
||||
|
||||
FT_ULong size_image_buffer;
|
||||
|
||||
SVG_RendererHooks hooks = svg_renderer->hooks;
|
||||
|
||||
|
||||
FT_UNUSED( mode );
|
||||
FT_UNUSED( origin );
|
||||
|
||||
if ( mode != FT_RENDER_MODE_NORMAL )
|
||||
return FT_THROW( Bad_Argument );
|
||||
|
||||
if ( svg_renderer->hooks_set == FALSE )
|
||||
{
|
||||
FT_TRACE1(( "Hooks are NOT set. Can't render OT-SVG glyphs\n" ));
|
||||
return FT_THROW( Missing_SVG_Hooks );
|
||||
}
|
||||
|
||||
if ( svg_renderer->loaded == FALSE )
|
||||
{
|
||||
FT_TRACE3(( "ft_svg_render: first rendering, calling init hook\n" ));
|
||||
error = hooks.init_svg( &svg_renderer->state );
|
||||
|
||||
svg_renderer->loaded = TRUE;
|
||||
}
|
||||
|
||||
ft_svg_preset_slot( (FT_Module)renderer, slot, TRUE );
|
||||
|
||||
size_image_buffer = (FT_ULong)slot->bitmap.pitch * slot->bitmap.rows;
|
||||
/* No `FT_QALLOC` here since we need a clean, empty canvas */
|
||||
/* to start with. */
|
||||
if ( FT_ALLOC( slot->bitmap.buffer, size_image_buffer ) )
|
||||
return error;
|
||||
|
||||
error = hooks.render_svg( slot, &svg_renderer->state );
|
||||
if ( error )
|
||||
FT_FREE( slot->bitmap.buffer );
|
||||
else
|
||||
slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static const SVG_Interface svg_interface =
|
||||
{
|
||||
(Preset_Bitmap_Func)ft_svg_preset_slot
|
||||
};
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
if ( value_is_string == TRUE )
|
||||
return FT_THROW( Invalid_Argument );
|
||||
|
||||
hooks = (SVG_RendererHooks*)value;
|
||||
|
||||
renderer->hooks = *hooks;
|
||||
renderer->hooks_set = TRUE;
|
||||
}
|
||||
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;
|
||||
|
||||
|
||||
FT_UNUSED( module );
|
||||
|
||||
result = ft_service_list_lookup( ft_svg_services, ft_svg_interface );
|
||||
if ( result )
|
||||
return result;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static FT_Error
|
||||
ft_svg_transform( FT_Renderer renderer,
|
||||
FT_GlyphSlot slot,
|
||||
const FT_Matrix* _matrix,
|
||||
const FT_Vector* _delta )
|
||||
{
|
||||
FT_SVG_Document doc = (FT_SVG_Document)slot->other;
|
||||
FT_Matrix* matrix = (FT_Matrix*)_matrix;
|
||||
FT_Vector* delta = (FT_Vector*)_delta;
|
||||
|
||||
FT_Matrix tmp_matrix;
|
||||
FT_Vector tmp_delta;
|
||||
|
||||
FT_Matrix a, b;
|
||||
FT_Pos x, y;
|
||||
|
||||
|
||||
FT_UNUSED( renderer );
|
||||
|
||||
if ( !matrix )
|
||||
{
|
||||
tmp_matrix.xx = 0x10000;
|
||||
tmp_matrix.xy = 0;
|
||||
tmp_matrix.yx = 0;
|
||||
tmp_matrix.yy = 0x10000;
|
||||
|
||||
matrix = &tmp_matrix;
|
||||
}
|
||||
|
||||
if ( !delta )
|
||||
{
|
||||
tmp_delta.x = 0;
|
||||
tmp_delta.y = 0;
|
||||
|
||||
delta = &tmp_delta;
|
||||
}
|
||||
|
||||
a = doc->transform;
|
||||
b = *matrix;
|
||||
FT_Matrix_Multiply( &b, &a );
|
||||
|
||||
|
||||
x = ADD_LONG( ADD_LONG( FT_MulFix( matrix->xx, doc->delta.x ),
|
||||
FT_MulFix( matrix->xy, doc->delta.y ) ),
|
||||
delta->x );
|
||||
y = ADD_LONG( ADD_LONG( FT_MulFix( matrix->yx, doc->delta.x ),
|
||||
FT_MulFix( matrix->yy, doc->delta.y ) ),
|
||||
delta->y );
|
||||
|
||||
doc->delta.x = x;
|
||||
doc->delta.y = y;
|
||||
doc->transform = a;
|
||||
|
||||
return FT_Err_Ok;
|
||||
}
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_SVG */
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_SVG
|
||||
#define PUT_SVG_MODULE( a ) a
|
||||
#define SVG_GLYPH_FORMAT FT_GLYPH_FORMAT_SVG
|
||||
#else
|
||||
#define PUT_SVG_MODULE( a ) NULL
|
||||
#define SVG_GLYPH_FORMAT FT_GLYPH_FORMAT_NONE
|
||||
#endif
|
||||
|
||||
|
||||
FT_DEFINE_RENDERER(
|
||||
ft_svg_renderer_class,
|
||||
|
||||
FT_MODULE_RENDERER,
|
||||
sizeof ( SVG_RendererRec ),
|
||||
|
||||
"ot-svg",
|
||||
0x10000L,
|
||||
0x20000L,
|
||||
|
||||
(const void*)PUT_SVG_MODULE( &svg_interface ), /* module specific interface */
|
||||
|
||||
(FT_Module_Constructor)PUT_SVG_MODULE( ft_svg_init ), /* module_init */
|
||||
(FT_Module_Destructor)PUT_SVG_MODULE( ft_svg_done ), /* module_done */
|
||||
PUT_SVG_MODULE( ft_svg_get_interface ), /* get_interface */
|
||||
|
||||
SVG_GLYPH_FORMAT,
|
||||
|
||||
(FT_Renderer_RenderFunc) PUT_SVG_MODULE( ft_svg_render ), /* render_glyph */
|
||||
(FT_Renderer_TransformFunc)PUT_SVG_MODULE( ft_svg_transform ), /* transform_glyph */
|
||||
NULL, /* get_glyph_cbox */
|
||||
NULL, /* set_mode */
|
||||
NULL /* raster_class */
|
||||
)
|
||||
|
||||
|
||||
/* END */
|
|
@ -0,0 +1,35 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* ftsvg.h
|
||||
*
|
||||
* The FreeType SVG renderer interface (specification).
|
||||
*
|
||||
* Copyright (C) 2022 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 <freetype/ftrender.h>
|
||||
#include <freetype/internal/ftobjs.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) 2022 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)ot-svg $(ECHO_DRIVER_DESC)OT-SVG glyph renderer module$(ECHO_DRIVER_DONE)
|
||||
endef
|
||||
|
||||
# EOF
|
|
@ -0,0 +1,70 @@
|
|||
#
|
||||
# FreeType 2 SVG renderer module build rules
|
||||
#
|
||||
|
||||
|
||||
# Copyright (C) 2022 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)
|
||||
|
||||
# SVG renderer sources (i.e., C files)
|
||||
#
|
||||
SVG_DRV_SRC := $(SVG_DIR)/ftsvg.c
|
||||
|
||||
|
||||
# SVG renderer headers
|
||||
#
|
||||
SVG_DRV_H := $(SVG_DIR)/ftsvg.h \
|
||||
$(SVG_DIR)/svgtypes.h
|
||||
|
||||
|
||||
# SVG renderer object(s)
|
||||
#
|
||||
# SVG_DRV_OBJ_M is used during `multi' builds.
|
||||
# SVG_DRV_OBJ_S is used during `single' builds.
|
||||
#
|
||||
SVG_DRV_OBJ_M := $(SVG_DRV_SRC:$(SVG_DIR)/%.c=$(OBJ_DIR)/%.$O)
|
||||
SVG_DRV_OBJ_S := $(OBJ_DIR)/svg.$O
|
||||
|
||||
# SVG renderer source file for single build
|
||||
#
|
||||
SVG_DRV_SRC_S := $(SVG_DIR)/svg.c
|
||||
|
||||
|
||||
# SVG renderer - 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))
|
||||
|
||||
|
||||
# SVG renderer - 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,24 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* svg.c
|
||||
*
|
||||
* FreeType SVG renderer module component (body only).
|
||||
*
|
||||
* Copyright (C) 2022 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 "svgtypes.h"
|
||||
#include "ftsvg.c"
|
||||
|
||||
|
||||
/* END */
|
|
@ -0,0 +1,42 @@
|
|||
/****************************************************************************
|
||||
*
|
||||
* svgtypes.h
|
||||
*
|
||||
* The FreeType SVG renderer internal types (specification).
|
||||
*
|
||||
* Copyright (C) 2022 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 SVGTYPES_H_
|
||||
#define SVGTYPES_H_
|
||||
|
||||
#include <ft2build.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
#include <freetype/ftrender.h>
|
||||
#include <freetype/otsvg.h>
|
||||
|
||||
|
||||
typedef struct SVG_RendererRec_
|
||||
{
|
||||
FT_RendererRec root; /* this inherits FT_RendererRec */
|
||||
FT_Bool loaded;
|
||||
FT_Bool hooks_set;
|
||||
SVG_RendererHooks hooks; /* this holds hooks for SVG rendering */
|
||||
FT_Pointer state; /* a place for hooks to store state, if needed */
|
||||
|
||||
} SVG_RendererRec;
|
||||
|
||||
typedef struct SVG_RendererRec_* SVG_Renderer;
|
||||
|
||||
#endif /* SVGTYPES_H_ */
|
||||
|
||||
|
||||
/* EOF */
|
Loading…
Reference in New Issue