Let FT handle the memory management for rendering port's state

and the image buffer.

State has been moved inside the library structure. A new hook
function has been added to query the size needed for the state
structure and this allocation is performed by FT. Memory alloc.
for the image buffer is also being done by FT so that it can later
free it easily.

* include/freetype/svgrenderer.h: Small doc fixes. Addition of two
new hooks. `SVG_Lib_Get_State_Size' and `SVG_Lib_Get_Buffer_Size'.

* src/base/ftglyph.c (FT_Glyph_To_Bitmap): Small bug fix. Memory
was being initialized before library.

* src/base/ftobjs.c (FT_Set_Svg_Hooks): Adjust the code for new
hook functions.

* src/svg/ftsvg.c: Adjust the code for new hook functions. Perform
all memory allocations needed by the rendering port from FreeType
side.

* src/svg/svgtypes.c: Add the new hooks in the hook structure.
This commit is contained in:
Moazin Khatti 2019-07-06 15:38:37 +05:00
parent de44a3fda8
commit 1f74524929
5 changed files with 126 additions and 35 deletions

View File

@ -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 );
/**************************************************************************
*

View File

@ -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;

View File

@ -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;
}

View File

@ -17,22 +17,12 @@
#include <ft2build.h>
#include FT_SVG_RENDERER_H
#include FT_BBOX_H
#include <stdio.h>
#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;
}

View File

@ -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_