[sdf] Implemented a few functions required by a renderer module.

This commit is contained in:
Anuj Verma 2020-06-20 10:30:39 +05:30 committed by anujverma
parent c9d1149923
commit 29c92db771
3 changed files with 173 additions and 26 deletions

View File

@ -1,3 +1,20 @@
2020-06-20 Anuj Verma <anujv@iitbhilai.ac.in>
[sdf] Implemented a few functions required by a renderer
module.
* src/sdf/ftsdf.c (sdf_TRaster_): Added new structure to hold
the memory allocator `FT_Memory'.
* src/sdf/ftsdf.c (ft_sdf_raster): Implemented a few essential
functions required by `FT_Raster'.
* src/sdf/ftsdfrend.c (ft_sdf_renderer_class): Implemented a few
essential functions required by `FT_Renderer'.
* src/sdf/ftsdfrend.c (ft_sdf_render): Added functionality to
compute shift and padding before rendering the outline.
2020-06-19 Anuj Verma <anujv@iitbhilai.ac.in>
* include/freetype/ftimage.h (FT_Render_Mode_): Added new
@ -27,7 +44,7 @@
* src/sdf/rules.mk, src/sdf/module.mk: Added files required to
build the `sdf' module using the default build system.
* CMakeLists.txt (`BASE_SRCS'): Add `src/sdf/sdf.c' to the variable.
* CMakeLists.txt (BASE_SRCS): Add `src/sdf/sdf.c' to the variable.
* include/freetype/config/ftmodule.h: Added `sdf' module
declaration so that the module can be compiled when not compiling

View File

@ -5,15 +5,37 @@
#include "ftsdferrs.h"
/**************************************************************************
*
* structures and enums
*
*/
typedef struct sdf_TRaster_
{
FT_Memory memory; /* used internally to allocate memory */
} sdf_TRaster;
/**************************************************************************
*
* interface functions
*
*/
static int
sdf_raster_new( FT_Memory memory,
FT_Raster* araster)
{
FT_Error error = FT_THROW( Unimplemented_Feature );
FT_Error error = FT_Err_Ok;
sdf_TRaster* raster = NULL;
FT_UNUSED( memory );
FT_UNUSED( araster );
*araster = 0;
if ( !FT_ALLOC( raster, sizeof( sdf_TRaster ) ) )
{
raster->memory = memory;
*araster = (FT_Raster)raster;
}
return error;
}
@ -23,6 +45,7 @@
unsigned char* pool_base,
unsigned long pool_size )
{
/* no use of this function */
FT_UNUSED( raster );
FT_UNUSED( pool_base );
FT_UNUSED( pool_size );
@ -33,6 +56,8 @@
unsigned long mode,
void* args )
{
/* Currently there is no use for this function but later */
/* it will be used to modify the `spread' parameter. */
FT_UNUSED( raster );
FT_UNUSED( mode );
FT_UNUSED( args );
@ -55,7 +80,10 @@
static void
sdf_raster_done( FT_Raster raster )
{
FT_UNUSED( raster );
FT_Memory memory = (FT_Memory)((sdf_TRaster*)raster)->memory;
FT_FREE( raster );
}
FT_DEFINE_RASTER_FUNCS(

View File

@ -1,69 +1,171 @@
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftobjs.h>
#include <freetype/ftoutln.h>
#include "ftsdfrend.h"
#include "ftsdf.h"
#include "ftsdferrs.h"
/* generate signed distance field from a glyph's slot image */
static FT_Error
ft_sdf_render( FT_Renderer render,
FT_GlyphSlot slot,
FT_Render_Mode mode,
const FT_Vector* origin )
{
FT_Error error = FT_THROW( Unimplemented_Feature );
FT_Error error = FT_Err_Ok;
FT_Outline* outline = &slot->outline;
FT_Bitmap* bitmap = &slot->bitmap;
FT_Memory memory = render->root.memory;
FT_Pos x_shift = 0;
FT_Pos y_shift = 0;
/* use hardcoded padding for now */
FT_UInt x_pad = 10;
FT_UInt y_pad = 10;
FT_Raster_Params params;
FT_UNUSED( render );
FT_UNUSED( slot );
FT_UNUSED( mode );
FT_UNUSED( origin );
/* check if slot format is correct before rendering */
if ( slot->format != render->glyph_format )
{
error = FT_THROW( Invalid_Argument );
goto Exit;
}
/* check if render mode is correct */
if ( mode != FT_RENDER_MODE_SDF )
{
FT_ERROR(( "ft_sdf_render: sdf module only"
"render when using `FT_RENDER_MODE_SDF'" ));
error = FT_THROW( Cannot_Render_Glyph );
goto Exit;
}
/* deallocate the previously allocated bitmap */
if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
{
FT_FREE( bitmap->buffer );
slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
}
/* preset the bitmap using the glyph's outline; */
/* the sdf bitmap is similar to a antialiased bitmap */
/* with a slighty bigger size and different pixel mode */
if ( ft_glyphslot_preset_bitmap( slot, FT_RENDER_MODE_NORMAL, origin ) )
{
error = FT_THROW( Raster_Overflow );
goto Exit;
}
if ( !bitmap->rows || !bitmap->pitch )
goto Exit;
/* apply the padding */
bitmap->rows += y_pad;
bitmap->width += x_pad;
/* ignore the pitch, pixel mode and set custom */
bitmap->pixel_mode = FT_PIXEL_MODE_GRAY16;
bitmap->pitch = bitmap->width * 2;
bitmap->num_grays = 65536;
/* allocate new buffer */
if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) )
goto Exit;
slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
x_shift = 64 * -( slot->bitmap_left + x_pad );
y_shift = 64 * -( slot->bitmap_top + y_pad );
y_shift += 64 * (FT_Int)bitmap->rows;
if ( origin )
{
x_shift += origin->x;
y_shift += origin->y;
}
/* translate outline to render it into the bitmap */
if ( x_shift || y_shift )
FT_Outline_Translate( outline, x_shift, y_shift );
/* set up parameters */
params.target = bitmap;
params.source = outline;
params.flags = 0;
/* render the outline */
error = render->raster_render( render->raster, &params );
Exit:
if ( !error )
{
/* the glyph is successfully rendered to a bitmap */
slot->format = FT_GLYPH_FORMAT_BITMAP;
}
else if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP )
{
FT_FREE( bitmap->buffer );
slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP;
}
if ( x_shift || y_shift )
FT_Outline_Translate( outline, -x_shift, -y_shift );
return error;
}
/* transform the glyph using matrix and/or delta */
static FT_Error
ft_sdf_transform( FT_Renderer render,
FT_GlyphSlot slot,
const FT_Matrix* matrix,
const FT_Vector* delta )
{
FT_Error error = FT_THROW( Unimplemented_Feature );
FT_Error error = FT_Err_Ok;
FT_UNUSED( render );
FT_UNUSED( slot );
FT_UNUSED( matrix );
FT_UNUSED( delta );
if ( slot->format != render->glyph_format )
{
error = FT_THROW( Invalid_Argument );
goto Exit;
}
if ( matrix )
FT_Outline_Transform( &slot->outline, matrix );
if ( delta )
FT_Outline_Translate( &slot->outline, delta->x, delta->y );
Exit:
return error;
}
/* returns the control box of glyph's outline */
static void
ft_sdf_get_cbox( FT_Renderer render,
FT_GlyphSlot slot,
FT_BBox* cbox )
{
FT_UNUSED( render );
FT_UNUSED( slot );
FT_UNUSED( cbox );
FT_ZERO( cbox );
if ( slot->format == render->glyph_format )
FT_Outline_Get_CBox( &slot->outline, cbox );
}
/* set render specific modes or attributes */
static FT_Error
ft_sdf_set_mode( FT_Renderer render,
FT_ULong mode_tag,
FT_Pointer data )
{
FT_Error error = FT_THROW( Unimplemented_Feature );
FT_UNUSED( render );
FT_UNUSED( mode_tag );
FT_UNUSED( data );
return error;
/* pass it to the rasterizer */
return render->clazz->raster_class->raster_set_mode( render->raster,
mode_tag,
data );
}
FT_DEFINE_RENDERER(