diff --git a/[GSoC]ChangeLog b/[GSoC]ChangeLog index 8bdeb6048..3181991aa 100644 --- a/[GSoC]ChangeLog +++ b/[GSoC]ChangeLog @@ -1,3 +1,39 @@ +2020-07-19 Anuj Verma + + [sdf] Added interface functions for `bsdf' converter. + + * src/base/ftobjs.c (FT_Render_Glyph_Internal): Remove + the bitmap check which prevent calling renderers + if the glyph is already a bitmap. The `bsdf' renderer + requires a bitmap for conversion. + + * src/base/ftobjs.c (ft_add_renderer): Remove the glyph + format check which ensures that the glyph format for + a renderer is `FT_GLYPH_FORMAT_OUTLINE', again the `bsdf' + renderer has `FT_GLYPH_FORMAT_BITMAP' as a glyph format, + so we need to remove the condition to initialize the + renderer properly. + + * src/sdf/ftbsdf.c (*): Added a rasterizer for the + `bsdf' renderer and created necessary functions. + + * src/sdf/ftbsdf.h: Add forward declaration of the + rasterizer. + + * src/sdf/ftsdfrend.c (ft_bitmap_sdf_renderer_class): + Define the new `bsdf' rendere and add the + `FT_Renderer_RenderFunc' function, the rest is + same as the `sdf' renderer. + + * src/sdf/ftsdfrend.h: Add forward declaration of the + renderer. + + * src/sdf/rules.mk (SDF_DRV_SRC): Add the new `ftbsdf.c' + file to the compile list. + + * src/sdf/sdf.c: Inclue the `ftbsdf.c' file if making + single object. + 2020-07-19 Anuj Verma [sdf] Add alloc/free functions. diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 8adfdffe1..94b697214 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -4393,8 +4393,7 @@ render->glyph_format = clazz->glyph_format; /* allocate raster object if needed */ - if ( clazz->glyph_format == FT_GLYPH_FORMAT_OUTLINE && - clazz->raster_class->raster_new ) + if ( clazz->raster_class->raster_new ) { error = clazz->raster_class->raster_new( memory, &render->raster ); if ( error ) @@ -4537,9 +4536,6 @@ switch ( slot->format ) { - case FT_GLYPH_FORMAT_BITMAP: /* already a bitmap, don't do anything */ - break; - default: if ( slot->internal->load_flags & FT_LOAD_COLOR ) { diff --git a/src/sdf/ftbsdf.c b/src/sdf/ftbsdf.c new file mode 100644 index 000000000..132949c75 --- /dev/null +++ b/src/sdf/ftbsdf.c @@ -0,0 +1,76 @@ + +#include +#include + +#include "ftsdf.h" +#include "ftsdferrs.h" + + /************************************************************************** + * + * interface functions + * + */ + + static FT_Error + bsdf_raster_new( FT_Memory memory, + FT_Raster* araster) + { + FT_UNUSED( memory ); + FT_UNUSED( araster ); + + return FT_Err_Ok; + } + + static void + bsdf_raster_reset( FT_Raster raster, + unsigned char* pool_base, + unsigned long pool_size ) + { + /* no use of this function */ + FT_UNUSED( raster ); + FT_UNUSED( pool_base ); + FT_UNUSED( pool_size ); + } + + static FT_Error + bsdf_raster_set_mode( FT_Raster raster, + unsigned long mode, + void* args ) + { + FT_UNUSED( raster ); + FT_UNUSED( mode ); + FT_UNUSED( args ); + + + return FT_Err_Ok; + } + + static FT_Error + bsdf_raster_render( FT_Raster raster, + const FT_Raster_Params* params ) + { + FT_UNUSED( raster ); + FT_UNUSED( params ); + + return FT_THROW( Unimplemented_Feature ) ; + } + + static void + bsdf_raster_done( FT_Raster raster ) + { + FT_UNUSED( raster ); + } + + FT_DEFINE_RASTER_FUNCS( + ft_bitmap_sdf_raster, + + FT_GLYPH_FORMAT_BITMAP, + + (FT_Raster_New_Func) bsdf_raster_new, /* raster_new */ + (FT_Raster_Reset_Func) bsdf_raster_reset, /* raster_reset */ + (FT_Raster_Set_Mode_Func) bsdf_raster_set_mode, /* raster_set_mode */ + (FT_Raster_Render_Func) bsdf_raster_render, /* raster_render */ + (FT_Raster_Done_Func) bsdf_raster_done /* raster_done */ + ) + +/* END */ diff --git a/src/sdf/ftsdf.h b/src/sdf/ftsdf.h index d06f59a8e..e44081ac8 100644 --- a/src/sdf/ftsdf.h +++ b/src/sdf/ftsdf.h @@ -53,8 +53,12 @@ FT_BEGIN_HEADER } SDF_Raster_Params; + /* rasterizer to convert outline to SDF */ FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_sdf_raster; + /* rasterizer to convert bitmap to SDF */ + FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_bitmap_sdf_raster; + FT_END_HEADER #endif /* FTSDF_H_ */ diff --git a/src/sdf/ftsdfrend.c b/src/sdf/ftsdfrend.c index ffe8f497b..bc7bcabf9 100644 --- a/src/sdf/ftsdfrend.c +++ b/src/sdf/ftsdfrend.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "ftsdfrend.h" #include "ftsdf.h" @@ -401,13 +402,108 @@ /*************************************************************************/ /*************************************************************************/ + /* generate signed distance field from glyph's bitmap */ static FT_Error ft_bsdf_render( FT_Renderer module, FT_GlyphSlot slot, FT_Render_Mode mode, const FT_Vector* origin ) { + FT_Error error = FT_Err_Ok; + FT_Bitmap* bitmap = &slot->bitmap; + FT_Memory memory = NULL; + FT_Renderer render = NULL; + FT_Bitmap target; + + FT_Pos x_pad = 0; + FT_Pos y_pad = 0; + + SDF_Raster_Params params; + SDF_Renderer sdf_module = SDF_RENDERER( module ); + + render = &sdf_module->root; + memory = render->root.memory; + + /* check if slot format is correct before rendering */ + if ( slot->format != render->glyph_format ) + { + FT_ERROR(( "[bsdf] ft_bsdf_render: " + "bsdf renderer require the slot " + "format to be a bitmap\n" )); + error = FT_THROW( Invalid_Glyph_Format ); + goto Exit; + } + + /* check if render mode is correct */ + if ( mode != FT_RENDER_MODE_SDF ) + { + FT_ERROR(( "[bsdf] ft_bsdf_render: " + "sdf module only render when " + "using `FT_RENDER_MODE_SDF'\n" )); + error = FT_THROW( Cannot_Render_Glyph ); + goto Exit; + } + + if ( origin ) + { + FT_ERROR(( "[bsdf] ft_bsdf_render: " + "bsdf renderer can't translate " + "the bitmap\n" )); + error = FT_THROW( Unimplemented_Feature ); + goto Exit; + } + + if ( !bitmap->rows || !bitmap->pitch ) + goto Exit; + + FT_Bitmap_New( &target ); + + /* the padding will simply be equal to the `spread' */ + x_pad = sdf_module->spread; + y_pad = sdf_module->spread; + + /* apply the padding, will be in all the directions */ + target.rows = bitmap->rows + y_pad * 2; + target.width = bitmap->width + x_pad * 2; + + /* setup the target bitmap */ + target.pixel_mode = FT_PIXEL_MODE_GRAY16; + target.pitch = target.width * 2; + target.num_grays = 65535; + + if ( FT_ALLOC_MULT( target.buffer, target.rows, target.pitch ) ) + goto Exit; + + /* set up parameters */ + params.root.target = ⌖ + params.root.source = bitmap; + params.root.flags = FT_RASTER_FLAG_SDF; + params.spread = sdf_module->spread; + params.flip_sign = sdf_module->flip_sign; + params.flip_y = sdf_module->flip_y; + + error = render->raster_render( render->raster, + (const FT_Raster_Params*)¶ms ); + Exit: + if ( !error ) + { + /* the glyph is successfully converted to a SDF */ + if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) + { + FT_FREE( bitmap->buffer ); + slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; + } + + slot->bitmap = target; + slot->internal->flags |= FT_GLYPH_OWN_BITMAP; + } + else if ( target.buffer ) + { + FT_FREE( target.buffer ); + } + + return error; } FT_DEFINE_RENDERER( @@ -433,7 +529,7 @@ (FT_Renderer_GetCBoxFunc) ft_sdf_get_cbox, /* get_glyph_cbox */ (FT_Renderer_SetModeFunc) ft_sdf_set_mode, /* set_mode */ - (FT_Raster_Funcs*)NULL /* raster_class */ + (FT_Raster_Funcs*)&ft_bitmap_sdf_raster /* raster_class */ ) /* END */ diff --git a/src/sdf/ftsdfrend.h b/src/sdf/ftsdfrend.h index 3ba7b9d7f..08525a3dd 100644 --- a/src/sdf/ftsdfrend.h +++ b/src/sdf/ftsdfrend.h @@ -57,7 +57,7 @@ FT_BEGIN_HEADER * convert bitmaps to signed distance fields. * * @note: - * This is not a seperate module, it is a part of the `sdf' module. + * This is not a separate module, it is a part of the `sdf' module. * */ FT_DECLARE_RENDERER( ft_bitmap_sdf_renderer_class ) diff --git a/src/sdf/rules.mk b/src/sdf/rules.mk index 214725eae..eba66faa9 100644 --- a/src/sdf/rules.mk +++ b/src/sdf/rules.mk @@ -16,7 +16,8 @@ SDF_COMPILE := $(CC) $(ANSIFLAGS) \ # sdf driver sources (i.e., C files) # SDF_DRV_SRC := $(SDF_DIR)/ftsdfrend.c \ - $(SDF_DIR)/ftsdf.c + $(SDF_DIR)/ftsdf.c \ + $(SDF_DIR)/ftbsdf.c # sdf driver headers diff --git a/src/sdf/sdf.c b/src/sdf/sdf.c index 5481c8f5d..7428758e9 100644 --- a/src/sdf/sdf.c +++ b/src/sdf/sdf.c @@ -4,6 +4,7 @@ #include "ftsdfrend.c" #include "ftsdf.c" +#include "ftbsdf.c" /* END */