* 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.fix-sdf-squared-distances
parent
97c09a803e
commit
0bf49bd229
17 changed files with 819 additions and 5 deletions
@ -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 */ |
@ -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