diff --git a/include/freetype/svgrenderer.h b/include/freetype/svgrenderer.h index e6c9aa49b..2f6e83fc4 100644 --- a/include/freetype/svgrenderer.h +++ b/include/freetype/svgrenderer.h @@ -80,15 +80,63 @@ FT_BEGIN_HEADER * A callback used to render the glyph loaded in the slot. * * @input: - * svg_doc:: - * A pointer to the svg document + * 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)( FT_GlyphSlot slot ); + (*SVG_Lib_Render)( FT_GlyphSlot slot, + FT_BBox outline_bbox); + + /************************************************************************** + * + * @functype: + * SVG_Lib_Get_State_Size + * + * @description: + * A callback which is called to query the size of the state stucture. + * This is used for allocating the state structure in library. + * + * @return: + * Size of the state structure in bytes. + */ + + typedef FT_UInt + (*SVG_Lib_Get_State_Size)( ); + + /************************************************************************** + * + * @functype: + * SVG_Lib_Get_Buffer_Size + * + * @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' 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)( FT_GlyphSlot slot, + FT_BBox bbox ); /************************************************************************** @@ -116,15 +164,25 @@ FT_BEGIN_HEADER * A function pointer of the type `SVG_Lib_Render'. Read the * documentation of `SVG_Lib_Render'. * + * get_state_size:: + * A function pointer of the type `SVG_Lib_Get_State_Size'. Read the + * documentation of `SVG_Lib_Get_State_Size'. + * + * get_buffer_size:: + * A function pointer of the type `SVG_Lib_Get_Buffer_Size'. Read the + * documentation of `SVG_Lib_Get_Buffer_Size'. + * * @return: * FreeType error code. 0 means success. */ typedef FT_Error - (*SVG_Set_Hooks)( FT_Module module, - SVG_Lib_Init init_hook, - SVG_Lib_Free free_hook, - SVG_Lib_Render render_hook ); + (*SVG_Set_Hooks)( FT_Module module, + SVG_Lib_Init init_hook, + SVG_Lib_Free free_hook, + SVG_Lib_Render render_hook, + SVG_Lib_Get_State_Size get_state_size, + SVG_Lib_Get_Buffer_Size get_buffer_size ); /************************************************************************** * @@ -151,10 +209,12 @@ FT_BEGIN_HEADER /* TODO: to document */ FT_EXPORT( FT_Error ) - FT_Set_Svg_Hooks( FT_Library library, - SVG_Lib_Init init_hook, - SVG_Lib_Free free_hook, - SVG_Lib_Render render_hook ); + FT_Set_Svg_Hooks( FT_Library library, + SVG_Lib_Init init_hook, + SVG_Lib_Free free_hook, + SVG_Lib_Render render_hook, + SVG_Lib_Get_State_Size get_state_size, + SVG_Lib_Get_Buffer_Size get_buffer_size ); /************************************************************************** * diff --git a/src/base/ftglyph.c b/src/base/ftglyph.c index ae6480b21..8d53281b7 100644 --- a/src/base/ftglyph.c +++ b/src/base/ftglyph.c @@ -716,7 +716,7 @@ const FT_Glyph_Class* clazz; FT_Library library; - FT_Memory memory = library->memory; + FT_Memory memory; /* check argument */ @@ -728,6 +728,7 @@ clazz = glyph->clazz; library = glyph->library; + memory = library->memory; if ( !library || !clazz ) goto Bad; diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index e4e1532b2..b72f5f2f0 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -5596,10 +5596,12 @@ } FT_EXPORT_DEF( FT_Error ) - FT_Set_Svg_Hooks( FT_Library library, - SVG_Lib_Init init_hook, - SVG_Lib_Free free_hook, - SVG_Lib_Render render_hook ) + FT_Set_Svg_Hooks( FT_Library library, + SVG_Lib_Init init_hook, + SVG_Lib_Free free_hook, + SVG_Lib_Render render_hook, + SVG_Lib_Get_State_Size get_state_size, + SVG_Lib_Get_Buffer_Size get_buffer_size ) { FT_Module renderer; SVG_Renderer_Interface *svg; @@ -5612,7 +5614,12 @@ return FT_THROW( Missing_Module ); svg = (SVG_Renderer_Interface*)renderer->clazz->module_interface; - svg->set_hooks(renderer, init_hook, free_hook, render_hook); + svg->set_hooks(renderer, + init_hook, + free_hook, + render_hook, + get_state_size, + get_buffer_size ); return FT_Err_Ok; } diff --git a/src/svg/ftsvg.c b/src/svg/ftsvg.c index 445cf6526..bf027c52f 100644 --- a/src/svg/ftsvg.c +++ b/src/svg/ftsvg.c @@ -17,22 +17,12 @@ #include #include FT_SVG_RENDERER_H +#include FT_BBOX_H #include #include "ftsvg.h" - /* tmp hook injection */ - FT_Error - tmp_svg_lib_init() - { - FT_Error error; - - error = FT_Err_Ok; - printf("Init svg\n"); - return error; - } - /* ft_svg_init */ static FT_Error ft_svg_init( SVG_Renderer svg_module ) @@ -46,8 +36,10 @@ ft_svg_done( SVG_Renderer svg_module ) { FT_Library library = svg_module->root.root.library; - if ( svg_module->loaded = TRUE ) + FT_Memory memory = library->memory; + if ( svg_module->loaded == TRUE ) svg_module->hooks.svg_lib_free( library ); + FT_FREE( library->svg_renderer_state ); svg_module->loaded = FALSE; } @@ -59,20 +51,45 @@ { 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; + + SVG_RendererHooks hooks = svg_renderer->hooks; + + unsigned long size_image_buffer; + if ( svg_renderer->loaded == FALSE ) { - error = svg_renderer->hooks.svg_lib_init( library ); + FT_MEM_ALLOC( library->svg_renderer_state, + hooks.svg_lib_get_state_size() ); + if ( error ) + return error; + error = hooks.svg_lib_init( library ); svg_renderer->loaded = TRUE; } - return svg_renderer->hooks.svg_lib_render( slot ); + + /* 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.svg_lib_get_buffer_size( slot, outline_bbox ); + + FT_MEM_ALLOC( slot->bitmap.buffer, size_image_buffer ); + if ( error ) + return error; + + return hooks.svg_lib_render( slot, outline_bbox ); } static FT_Error - ft_svg_set_hooks( FT_Module module, - SVG_Lib_Init init_hook, - SVG_Lib_Free free_hook, - SVG_Lib_Render render_hook ) + ft_svg_set_hooks( FT_Module module, + SVG_Lib_Init init_hook, + SVG_Lib_Free free_hook, + SVG_Lib_Render render_hook, + SVG_Lib_Get_State_Size get_state_size, + SVG_Lib_Get_Buffer_Size get_buffer_size ) { SVG_Renderer renderer; @@ -81,6 +98,9 @@ renderer->hooks.svg_lib_free = free_hook; renderer->hooks.svg_lib_render = render_hook; + renderer->hooks.svg_lib_get_state_size = get_state_size; + renderer->hooks.svg_lib_get_buffer_size = get_buffer_size; + return FT_Err_Ok; } diff --git a/src/svg/svgtypes.c b/src/svg/svgtypes.c index 57e5c013d..d3938581d 100644 --- a/src/svg/svgtypes.c +++ b/src/svg/svgtypes.c @@ -27,6 +27,9 @@ SVG_Lib_Init svg_lib_init; SVG_Lib_Free svg_lib_free; SVG_Lib_Render svg_lib_render; + + SVG_Lib_Get_State_Size svg_lib_get_state_size; + SVG_Lib_Get_Buffer_Size svg_lib_get_buffer_size; } SVG_RendererHooks; typedef struct SVG_RendererRec_