diff options
Diffstat (limited to 'src/svg/ftsvg.c')
-rw-r--r-- | src/svg/ftsvg.c | 208 |
1 files changed, 208 insertions, 0 deletions
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 <ft2build.h> +#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 <stdio.h> + +#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 + ) |