diff --git a/include/freetype/fterrdef.h b/include/freetype/fterrdef.h index 9bc7dc65e..d58699baa 100644 --- a/include/freetype/fterrdef.h +++ b/include/freetype/fterrdef.h @@ -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, + "hooks have not been set" ) /* CFF, CID, and Type 1 errors */ diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h index 2f2050921..a89caa7d4 100644 --- a/include/freetype/internal/ftobjs.h +++ b/include/freetype/internal/ftobjs.h @@ -890,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_ { @@ -917,6 +921,9 @@ FT_BEGIN_HEADER FT_Int refcount; +#ifdef FT_CONFIG_OPTION_SVG + void* svg_renderer_state; +#endif } FT_LibraryRec; diff --git a/include/freetype/internal/fttrace.h b/include/freetype/internal/fttrace.h index f5f959804..1828addca 100644 --- a/include/freetype/internal/fttrace.h +++ b/include/freetype/internal/fttrace.h @@ -39,6 +39,7 @@ FT_TRACE_DEF( mm ) /* MM interface (ftmm.c) */ FT_TRACE_DEF( psprops ) /* PS driver properties (ftpsprop.c) */ FT_TRACE_DEF( raccess ) /* resource fork accessor (ftrfork.c) */ FT_TRACE_DEF( raster ) /* monochrome rasterizer (ftraster.c) */ +FT_TRACE_DEF( otsvg ) /* ot-svg renderer (ftsvg.c) */ FT_TRACE_DEF( smooth ) /* anti-aliasing raster (ftgrays.c) */ FT_TRACE_DEF( synth ) /* bold/slant synthesizer (ftsynth.c) */ diff --git a/include/freetype/internal/internal.h b/include/freetype/internal/internal.h index 3c8830f7e..79df6d74e 100644 --- a/include/freetype/internal/internal.h +++ b/include/freetype/internal/internal.h @@ -37,6 +37,7 @@ #define FT_INTERNAL_SERVICE_H #define FT_INTERNAL_RFORK_H #define FT_INTERNAL_VALIDATE_H +#define FT_INTERNAL_SVG_INTERFACE_H #define FT_INTERNAL_TRUETYPE_TYPES_H #define FT_INTERNAL_TYPE1_TYPES_H diff --git a/include/freetype/internal/svginterface.h b/include/freetype/internal/svginterface.h new file mode 100644 index 000000000..6ff6db02f --- /dev/null +++ b/include/freetype/internal/svginterface.h @@ -0,0 +1,42 @@ +/**************************************************************************** + * + * svginterface.h + * + * Exposes the interface of ot-svg module + * + * 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 SVGINTERFACE_H +#define SVGINTERFACE_H + +#include +#include FT_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 diff --git a/include/freetype/otsvg.h b/include/freetype/otsvg.h index 5569ce4d6..b7b9af8cc 100644 --- a/include/freetype/otsvg.h +++ b/include/freetype/otsvg.h @@ -30,6 +30,96 @@ 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. + * + * @return: + * FreeType error code. 0 means success. + */ + + typedef FT_Error + (*SVG_Lib_Render_Func)( FT_GlyphSlot slot ); + + /************************************************************************** + * + * @functype: + * SVG_Lib_Preset_Slot_Func + * + * @description: + * A callback used to preset the glyphslot. + * + * @input: + * slot :: + * The glyph slot which has the SVG document loaded. + * + * @return: + * FreeType error code. 0 means success. + */ + + typedef FT_Error + (*SVG_Lib_Preset_Slot_Func)( FT_GlyphSlot slot, FT_Bool cache); + + + 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_Preset_Slot_Func preset_slot; + } SVG_RendererHooks; + + /************************************************************************** * * @struct: diff --git a/modules.cfg b/modules.cfg index dc6c8d42d..14ac1e5bc 100644 --- a/modules.cfg +++ b/modules.cfg @@ -99,6 +99,9 @@ RASTER_MODULES += raster # Anti-aliasing rasterizer. RASTER_MODULES += smooth +# OT-SVG +RASTER_MODULES += svg + #### #### auxiliary modules diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 31fc23936..770002e45 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -28,6 +28,7 @@ #include FT_INTERNAL_STREAM_H #include FT_INTERNAL_SFNT_H /* for SFNT_Load_Table_Func */ #include FT_INTERNAL_POSTSCRIPT_AUX_H /* for PS_Driver */ +#include FT_INTERNAL_SVG_INTERFACE_H #include FT_TRUETYPE_TABLES_H #include FT_TRUETYPE_TAGS_H @@ -363,6 +364,7 @@ { FT_Outline* outline = &slot->outline; FT_Bitmap* bitmap = &slot->bitmap; + FT_Module module; FT_Pixel_Mode pixel_mode; @@ -374,7 +376,19 @@ if ( slot->format != FT_GLYPH_FORMAT_OUTLINE ) + { + if ( slot->format == FT_GLYPH_FORMAT_SVG ) + { + SVG_Service svg_service; + + module = FT_Get_Module(slot->library, "ot-svg" ); + svg_service = (SVG_Service)module->clazz->module_interface; + return svg_service->preset_slot( module, slot, FALSE ); + } + else + return 1; return 1; + } if ( origin ) { @@ -629,6 +643,7 @@ FT_FREE( slot->internal ); } + } @@ -4445,6 +4460,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 ); @@ -4580,7 +4602,6 @@ { case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */ break; - default: if ( slot->internal->load_flags & FT_LOAD_COLOR ) { @@ -5588,5 +5609,4 @@ return 0; } - /* END */ diff --git a/src/svg/ftsvg.c b/src/svg/ftsvg.c new file mode 100644 index 000000000..901f3e82e --- /dev/null +++ b/src/svg/ftsvg.c @@ -0,0 +1,208 @@ +/**************************************************************************** + * + * 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 +#include FT_INTERNAL_DEBUG_H +#include FT_SERVICE_PROPERTIES_H +#include FT_OTSVG_H +#include FT_INTERNAL_SVG_INTERFACE_H +#include FT_BBOX_H + +#include + +#include "ftsvg.h" + +#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 ) + { + FT_Library library = svg_module->root.root.library; + if ( svg_module->loaded == TRUE && + svg_module->hooks_set == TRUE ) + svg_module->hooks.free_svg( library ); + 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 ); + } + + return hooks.preset_slot( slot, cache ); + } + + 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; + + 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( library ); + svg_renderer->loaded = TRUE; + } + + ft_svg_preset_slot( (FT_Module)renderer, slot, TRUE); + size_image_buffer = slot->bitmap.pitch * slot->bitmap.rows; + FT_MEM_ALLOC( slot->bitmap.buffer, size_image_buffer); + if ( error ) + return error; + + return hooks.render_svg( slot ); + } + + 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 = (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; + + + result = ft_service_list_lookup( ft_svg_services, ft_svg_interface ); + if ( result ) + return result; + return 0; + } + +#endif + +#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*)&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 ), + NULL, + NULL, + NULL, + NULL + ) diff --git a/src/svg/ftsvg.h b/src/svg/ftsvg.h new file mode 100644 index 000000000..74cc76760 --- /dev/null +++ b/src/svg/ftsvg.h @@ -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 +#include FT_RENDER_H + +FT_BEGIN_HEADER + + FT_DECLARE_RENDERER( ft_svg_renderer_class ) + +FT_END_HEADER + +#endif /* FTSVG_H_ */ + +/* END */ diff --git a/src/svg/module.mk b/src/svg/module.mk new file mode 100644 index 000000000..eda4006c7 --- /dev/null +++ b/src/svg/module.mk @@ -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 diff --git a/src/svg/rules.mk b/src/svg/rules.mk new file mode 100644 index 000000000..3e4c039fb --- /dev/null +++ b/src/svg/rules.mk @@ -0,0 +1,69 @@ +# +# 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) + +# svg renderer sources (i.e., C files) +# +SVG_DRV_SRC := $(SVG_DIR)/ftsvg.c \ + $(SVG_DIR)/svgtypes.c + + +# svg renderer headers +# +SVG_DRV_H := $(SVG_DIR)/ftsvg.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 diff --git a/src/svg/svg.c b/src/svg/svg.c new file mode 100644 index 000000000..baa720ce9 --- /dev/null +++ b/src/svg/svg.c @@ -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 + +#include "svgtypes.c" +#include "ftsvg.c" + + +/* END */ diff --git a/src/svg/svgtypes.c b/src/svg/svgtypes.c new file mode 100644 index 000000000..19514347e --- /dev/null +++ b/src/svg/svgtypes.c @@ -0,0 +1,32 @@ +/**************************************************************************** + * + * svgtypes.h + * + * 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 +#include FT_INTERNAL_OBJECTS_H +#include FT_RENDER_H +#include FT_OTSVG_H + + typedef struct SVG_RendererRec_ + { + FT_RendererRec root; /* This inherits FT_RendererRec */ + FT_Bool loaded; + FT_Bool hooks_set; + SVG_RendererHooks hooks; /* Holds out hooks to the outside library */ + } SVG_RendererRec; + + typedef struct SVG_RendererRec_* SVG_Renderer; +