From d019c05e9f19ee6910ca47dc9864b83bfa53bbf5 Mon Sep 17 00:00:00 2001 From: Anurag Thakur Date: Fri, 29 Oct 2021 00:23:34 +0530 Subject: [PATCH] Finish importing code, integration pending --- include/freetype/config/ftmodule.h | 2 + src/dense/ftdense.c | 292 +++++++---------------------- src/dense/ftdense.h | 15 +- src/dense/ftdenserend.c | 177 ++--------------- src/dense/ftdenserend.h | 57 +----- 5 files changed, 93 insertions(+), 450 deletions(-) diff --git a/include/freetype/config/ftmodule.h b/include/freetype/config/ftmodule.h index b315baba8..992d48de2 100644 --- a/include/freetype/config/ftmodule.h +++ b/include/freetype/config/ftmodule.h @@ -29,5 +29,7 @@ FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class ) FT_USE_MODULE( FT_Renderer_Class, ft_sdf_renderer_class ) FT_USE_MODULE( FT_Renderer_Class, ft_bitmap_sdf_renderer_class ) FT_USE_MODULE( FT_Renderer_Class, ft_svg_renderer_class ) +FT_USE_MODULE( FT_Renderer_Class, ft_dense_renderer_class ) + /* EOF */ diff --git a/src/dense/ftdense.c b/src/dense/ftdense.c index 4f83c934e..f2df0517e 100644 --- a/src/dense/ftdense.c +++ b/src/dense/ftdense.c @@ -3,11 +3,11 @@ #undef FT_COMPONENT #define FT_COMPONENT dense +#include "ftdense.h" #include #include #include #include -#include "ftdense.h" #include "ftdenseerrs.h" @@ -29,18 +29,20 @@ Lerp( float aT, RasterFP_Point aP0, RasterFP_Point aP1 ) static int dense_move_to( const FT_Vector* to, RasterFP* aRasterFP ) { - - RasterFP_Point lp = {to->x, to->y}; + RasterFP_Point lp = { to->x, to->y }; aRasterFP->last_point = lp; return 0; } + + + static int dense_line_to( const FT_Vector* to, RasterFP* aRasterFP ) { - RasterFP_Point tp = {to->x, to->y}; - RasterFP_DrawLine(aRasterFP, aRasterFP->last_point, tp); + RasterFP_Point tp = { to->x, to->y }; + RasterFP_DrawLine( aRasterFP, aRasterFP->last_point, tp ); return 0; } @@ -201,14 +203,15 @@ RasterFP_DrawLine( RasterFP* aRasterFP, RasterFP_Point aP0, RasterFP_Point aP1 ) + static int dense_conic_to( const FT_Vector* control, - const FT_Vector* to, - RasterFP* aRasterFP) + const FT_Vector* to, + RasterFP* aRasterFP ) { - RasterFP_Point controlP = {control->x, control->y}; - RasterFP_Point toP = {to->x, to->y}; - RasterFP_DrawQuadratic( aRasterFP, aRasterFP->last_point, controlP, toP ); + RasterFP_Point controlP = { control->x, control->y }; + RasterFP_Point toP = { to->x, to->y }; + RasterFP_DrawQuadratic( aRasterFP, aRasterFP->last_point, controlP, toP ); return 0; } @@ -271,17 +274,17 @@ RasterFP_DrawQuadratic( RasterFP* aRasterFP, + + static int dense_cubic_to( const FT_Vector* control1, - const FT_Vector* control2, - const FT_Vector* to, - RasterFP* aRasterFP ) + const FT_Vector* control2, + const FT_Vector* to, + RasterFP* aRasterFP ) { - - RasterFP_Point ap1 = {control1->x, control1->y}; - RasterFP_Point ap2 = {control2->x, control2->y}; - RasterFP_Point ap3 = {to->x, to->y}; - + RasterFP_Point ap1 = { control1->x, control1->y }; + RasterFP_Point ap2 = { control2->x, control2->y }; + RasterFP_Point ap3 = { to->x, to->y }; RasterFP_DrawCubic( aRasterFP, aRasterFP->last_point, ap1, ap2, ap3 ); return 0; @@ -328,13 +331,10 @@ RasterFP_DrawCubic( RasterFP* aRasterFP, RasterFP_DrawLine( aRasterFP, p, aP3 ); } - - - static int dense_raster_new( FT_Memory memory, dense_PRaster* araster ) { - FT_Error error; + FT_Error error; dense_PRaster raster; if ( !FT_NEW( raster ) ) @@ -353,11 +353,10 @@ dense_raster_done( FT_Raster raster ) FT_FREE( raster ); } - static void dense_raster_reset( FT_Raster raster, - unsigned char* pool_base, - unsigned long pool_size ) + unsigned char* pool_base, + unsigned long pool_size ) { FT_UNUSED( raster ); FT_UNUSED( pool_base ); @@ -374,143 +373,43 @@ dense_raster_set_mode( FT_Raster raster, unsigned long mode, void* args ) return 0; /* nothing to do */ } -FT_DEFINE_OUTLINE_FUNCS( - func_interface, +FT_DEFINE_OUTLINE_FUNCS( dense_decompose_funcs, - (FT_Outline_MoveTo_Func)dense_move_to, /* move_to */ - (FT_Outline_LineTo_Func)dense_line_to, /* line_to */ - (FT_Outline_ConicTo_Func)dense_conic_to, /* conic_to */ - (FT_Outline_CubicTo_Func)dense_cubic_to, /* cubic_to */ + (FT_Outline_MoveTo_Func)dense_move_to, /* move_to */ + (FT_Outline_LineTo_Func)dense_line_to, /* line_to */ + (FT_Outline_ConicTo_Func)dense_conic_to, /* conic_to */ + (FT_Outline_CubicTo_Func)dense_cubic_to, /* cubic_to */ - 0, /* shift */ - 0 /* delta */ + 0, /* shift */ + 0 /* delta */ ) - - - - - - - static int -gray_convert_glyph_inner( RAS_ARG, int continued ) +dense_render_glyph( RasterFP* aRasterFP, FT_Bitmap* target ) { - int error; + FT_Error error = FT_Outline_Decompose( aRasterFP->outline, + &dense_decompose_funcs, aRasterFP ); - if ( ft_setjmp( ras.jump_buffer ) == 0 ) + // Render into bitmap + const float* source = aRasterFP->m_a; + unsigned char* dest = target->buffer; + unsigned char* dest_end = target->buffer + aRasterFP->m_w * aRasterFP->m_h; + float value = 0.0f; + while ( dest < dest_end ) { - if ( continued ) - FT_Trace_Disable(); - error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras ); - if ( continued ) - FT_Trace_Enable(); - - FT_TRACE7( ( "band [%d..%d]: %ld cell%s remaining/\n", ras.min_ey, - ras.max_ey, ras.cell_null - ras.cell_free, - ras.cell_null - ras.cell_free == 1 ? "" : "s" ) ); - } - else - { - error = FT_THROW( Raster_Overflow ); - - FT_TRACE7( ( "band [%d..%d]: to be bisected\n", ras.min_ey, ras.max_ey ) ); - } - - return error; -} - -static int gray_convert_glyph( RAS_ARG ) -{ - const TCoord yMin = ras.min_ey; - const TCoord yMax = ras.max_ey; - - TCell buffer[FT_MAX_GRAY_POOL]; - size_t height = (size_t)( yMax - yMin ); - size_t n = FT_MAX_GRAY_POOL / 8; - TCoord y; - TCoord bands[32]; /* enough to accommodate bisections */ - TCoord* band; - - int continued = 0; - - /* Initialize the null cell at the end of the poll. */ - ras.cell_null = buffer + FT_MAX_GRAY_POOL - 1; - ras.cell_null->x = CELL_MAX_X_VALUE; - ras.cell_null->area = 0; - ras.cell_null->cover = 0; - ras.cell_null->next = NULL; - - /* set up vertical bands */ - ras.ycells = (PCell*)buffer; - - if ( height > n ) - { - /* two divisions rounded up */ - n = ( height + n - 1 ) / n; - height = ( height + n - 1 ) / n; - } - - for ( y = yMin; y < yMax; ) - { - ras.min_ey = y; - y += height; - ras.max_ey = FT_MIN( y, yMax ); - - band = bands; - band[1] = ras.min_ey; - band[0] = ras.max_ey; - - do + value += *source++; + if ( value > 0.0f ) { - TCoord width = band[0] - band[1]; - TCoord w; - int error; - - for ( w = 0; w < width; ++w ) - ras.ycells[w] = ras.cell_null; - - /* memory management: skip ycells */ - n = ( width * sizeof( PCell ) + sizeof( TCell ) - 1 ) / sizeof( TCell ); - - ras.cell_free = buffer + n; - ras.cell = ras.cell_null; - ras.min_ey = band[1]; - ras.max_ey = band[0]; - ras.count_ey = width; - - error = gray_convert_glyph_inner( RAS_VAR, continued ); - continued = 1; - - if ( !error ) - { - if ( ras.render_span ) /* for FT_RASTER_FLAG_DIRECT only */ - gray_sweep_direct( RAS_VAR ); - else - gray_sweep( RAS_VAR ); - band--; - continue; - } - else if ( error != Smooth_Err_Raster_Overflow ) - return error; - - /* render pool overflow; we will reduce the render band by half */ - width >>= 1; - - /* this should never happen even with tiny rendering pool */ - if ( width == 0 ) - { - FT_TRACE7( ( "gray_convert_glyph: rotten glyph\n" ) ); - return FT_THROW( Raster_Overflow ); - } - - band++; - band[1] = band[0]; - band[0] += width; - } while ( band >= bands ); + int n = (int)( fabs( value ) * 255.0f + 0.5f ); + if ( n > 255 ) + n = 255; + *dest = (unsigned char)n; + } + else + *dest = 0; + dest++; } - - return Smooth_Err_Ok; + return error; } static int @@ -519,94 +418,39 @@ dense_raster_render( FT_Raster raster, const FT_Raster_Params* params ) const FT_Outline* outline = (const FT_Outline*)params->source; const FT_Bitmap* target_map = params->target; -#ifndef FT_STATIC_RASTER - gray_TWorker worker[1]; -#endif + RasterFP* aRasterFP = malloc( sizeof( RasterFP ) ); if ( !raster ) return FT_THROW( Invalid_Argument ); - /* this version does not support monochrome rendering */ - if ( !( params->flags & FT_RASTER_FLAG_AA ) ) - return FT_THROW( Cannot_Render_Glyph ); - if ( !outline ) return FT_THROW( Invalid_Outline ); - /* return immediately if the outline is empty */ - if ( outline->n_points == 0 || outline->n_contours <= 0 ) - return Smooth_Err_Ok; + aRasterFP->outline = outline; - if ( !outline->contours || !outline->points ) - return FT_THROW( Invalid_Outline ); + if ( !target_map ) + return FT_THROW( Invalid_Argument ); - if ( outline->n_points != outline->contours[outline->n_contours - 1] + 1 ) - return FT_THROW( Invalid_Outline ); + /* nothing to do */ + if ( !target_map->width || !target_map->rows ) + return 0; - ras.outline = *outline; + if ( !target_map->buffer ) + return FT_THROW( Invalid_Argument ); - if ( params->flags & FT_RASTER_FLAG_DIRECT ) - { - if ( !params->gray_spans ) - return Smooth_Err_Ok; - - ras.render_span = (FT_Raster_Span_Func)params->gray_spans; - ras.render_span_data = params->user; - - ras.min_ex = params->clip_box.xMin; - ras.min_ey = params->clip_box.yMin; - ras.max_ex = params->clip_box.xMax; - ras.max_ey = params->clip_box.yMax; - } - else - { - /* if direct mode is not set, we must have a target bitmap */ - if ( !target_map ) - return FT_THROW( Invalid_Argument ); - - /* nothing to do */ - if ( !target_map->width || !target_map->rows ) - return Smooth_Err_Ok; - - if ( !target_map->buffer ) - return FT_THROW( Invalid_Argument ); - - if ( target_map->pitch < 0 ) - ras.target.origin = target_map->buffer; - else - ras.target.origin = - target_map->buffer + - ( target_map->rows - 1 ) * (unsigned int)target_map->pitch; - - ras.target.pitch = target_map->pitch; - - ras.render_span = (FT_Raster_Span_Func)NULL; - ras.render_span_data = NULL; - - ras.min_ex = 0; - ras.min_ey = 0; - ras.max_ex = (FT_Pos)target_map->width; - ras.max_ey = (FT_Pos)target_map->rows; - } + aRasterFP->m_origin_x = 0; + aRasterFP->m_origin_y = 0; + aRasterFP->m_w = (float)target_map->width; + aRasterFP->m_h = (float)target_map->rows; /* exit if nothing to do */ - if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey ) - return Smooth_Err_Ok; + if ( aRasterFP->m_w <= aRasterFP->m_origin_x || + aRasterFP->m_h <= aRasterFP->m_origin_y ) + return 0; - return gray_convert_glyph( RAS_VAR ); + return dense_render_glyph( aRasterFP, target_map ); } - - - - - - - - - - - FT_DEFINE_RASTER_FUNCS( ft_dense_raster, diff --git a/src/dense/ftdense.h b/src/dense/ftdense.h index bf208d146..e7c4c826c 100644 --- a/src/dense/ftdense.h +++ b/src/dense/ftdense.h @@ -7,7 +7,6 @@ #include FT_CONFIG_CONFIG_H #include - FT_BEGIN_HEADER /************************************************************************** @@ -52,17 +51,11 @@ FT_BEGIN_HEADER * exception is `overlaps`, which gets ignored by the 'bsdf' renderer. * */ -typedef struct DENSE_Raster_Params_ -{ - FT_Raster_Params root; - FT_UInt spread; - FT_Bool flip_sign; - FT_Bool flip_y; - FT_Bool overlaps; - -} DENSE_Raster_Params; /* rasterizer to convert outline to SDF */ +#ifndef FT_EXPORT_VAR +#define FT_EXPORT_VAR( x ) extern x +#endif FT_EXPORT_VAR( const FT_Raster_Funcs ) ft_dense_raster; /** @@ -114,6 +107,8 @@ extern "C" int m_origin_y; RasterFP_Point last_point; + + FT_Outline *outline; } RasterFP; void RasterFP_Create( RasterFP* aRasterFP ); diff --git a/src/dense/ftdenserend.c b/src/dense/ftdenserend.c index 75c5771df..983f52a71 100644 --- a/src/dense/ftdenserend.c +++ b/src/dense/ftdenserend.c @@ -19,122 +19,7 @@ #undef FT_COMPONENT #define FT_COMPONENT dense -/************************************************************************** - * - * macros and default property values - * - */ -#define DENSE_RENDERER( rend ) ( (DENSE_Renderer)rend ) -/************************************************************************** - * - * for setting properties - * - */ - -/* property setter function */ -static FT_Error -dense_property_set( FT_Module module, - const char* property_name, - const void* value, - FT_Bool value_is_string ) -{ - FT_Error error = FT_Err_Ok; - DENSE_Renderer render = DENSE_RENDERER( FT_RENDERER( module ) ); - - FT_UNUSED( value_is_string ); - - if ( ft_strcmp( property_name, "spread" ) == 0 ) - { - // FT_Int val = *(const FT_Int*)value; - // if ( val > MAX_SPREAD || val < MIN_SPREAD ) - // { - // FT_TRACE0( - // ( "[sdf] dense_property_set:" - // " the `spread' property can have a value\n" ) ); - // FT_TRACE0( - // ( " " - // " within range [%d, %d] (value provided: %d)\n", - // MIN_SPREAD, MAX_SPREAD, val ) ); - // - // error = FT_THROW( Invalid_Argument ); - // goto Exit; - // } - // - // render->spread = (FT_UInt)val; - // FT_TRACE7( - // ( "[sdf] dense_property_set:" - // " updated property `spread' to %d\n", - // val ) ); - } - - else if ( ft_strcmp( property_name, "flip_sign" ) == 0 ) - { - ; - } - - else - { - FT_TRACE0( - ( "[dense] dense_property_set:" - " missing property `%s'\n", - property_name ) ); - error = FT_THROW( Missing_Property ); - } - -Exit: - return error; -} - -/* property getter function */ -static FT_Error -dense_property_get( FT_Module module, const char* property_name, void* value ) -{ - FT_Error error = FT_Err_Ok; - DENSE_Renderer render = DENSE_RENDERER( FT_RENDERER( module ) ); - - if ( ft_strcmp( property_name, "spread" ) == 0 ) - { - // FT_Int* val = (FT_Int*)value; - - // *val = render->spread; - } - - else if ( ft_strcmp( property_name, "flip_sign" ) == 0 ) - { - ; - } - - else - { - FT_TRACE0( - ( "[dense] dense_property_get:" - " missing property `%s'\n", - property_name ) ); - error = FT_THROW( Missing_Property ); - } - - return error; -} - -FT_DEFINE_SERVICE_PROPERTIESREC( - dense_service_properties, - - (FT_Properties_SetFunc)dense_property_set, /* set_property */ - (FT_Properties_GetFunc)dense_property_get ) /* get_property */ - -FT_DEFINE_SERVICEDESCREC1( dense_services, - - FT_SERVICE_ID_PROPERTIES, - &dense_service_properties ) - -static FT_Module_Interface -ft_dense_requester( FT_Renderer render, const char* module_interface ) -{ - FT_UNUSED( render ); - - return ft_service_list_lookup( dense_services, module_interface ); -} /************************************************************************** * @@ -145,7 +30,7 @@ ft_dense_requester( FT_Renderer render, const char* module_interface ) static FT_Error ft_dense_init( FT_Renderer render ) { - DENSE_Renderer dense_render = DENSE_RENDERER( render ); + FT_Renderer dense_render = render; // dense_render->spread = 0; // dense_render->flip_sign = 0; @@ -161,9 +46,9 @@ ft_dense_done( FT_Renderer render ) FT_UNUSED( render ); } -/* generate signed distance field from a glyph's slot image */ +/* generate bitmap from a glyph's slot image */ static FT_Error -ft_dense_render( FT_Renderer module, +ft_dense_render( FT_Renderer render, FT_GlyphSlot slot, FT_Render_Mode mode, const FT_Vector* origin ) @@ -172,19 +57,11 @@ ft_dense_render( FT_Renderer module, FT_Outline* outline = &slot->outline; FT_Bitmap* bitmap = &slot->bitmap; FT_Memory memory = NULL; - FT_Renderer render = NULL; FT_Pos x_shift = 0; FT_Pos y_shift = 0; - FT_Pos x_pad = 0; - FT_Pos y_pad = 0; - - DENSE_Raster_Params params; - DENSE_Renderer dense_module = DENSE_RENDERER( module ); - - render = &dense_module->root; - memory = render->root.memory; + FT_Raster_Params params; /* check whether slot format is correct before rendering */ if ( slot->format != render->glyph_format ) @@ -193,16 +70,6 @@ ft_dense_render( FT_Renderer module, goto Exit; } - /* check whether render mode is correct */ - if ( mode != FT_RENDER_MODE_NORMAL ) - { - FT_ERROR( - ( "[dense] ft_dense_render:" - " sdf module only render when" - " using `FT_RENDER_MODE_NORMAL'\n" ) ); - error = FT_THROW( Cannot_Render_Glyph ); - goto Exit; - } /* deallocate the previously allocated bitmap */ if ( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) @@ -212,9 +79,7 @@ ft_dense_render( FT_Renderer module, } /* preset the bitmap using the glyph's outline; */ - /* the sdf bitmap is similar to an antialiased bitmap */ - /* with a slightly bigger size and different pixel mode */ - if ( ft_glyphslot_preset_bitmap( slot, FT_RENDER_MODE_NORMAL, origin ) ) + if ( ft_glyphslot_preset_bitmap( slot, mode, origin ) ) { error = FT_THROW( Raster_Overflow ); goto Exit; @@ -223,27 +88,22 @@ ft_dense_render( FT_Renderer module, if ( !bitmap->rows || !bitmap->pitch ) goto Exit; - /* the padding will simply be equal to the `spread' */ - x_pad = dense_module->spread; - y_pad = dense_module->spread; - - /* apply the padding; will be in all the directions */ - bitmap->rows += y_pad * 2; - bitmap->width += x_pad * 2; - /* ignore the pitch, pixel mode and set custom */ bitmap->pixel_mode = FT_PIXEL_MODE_GRAY; bitmap->pitch = bitmap->width; bitmap->num_grays = 255; - /* allocate new buffer */ + + /* allocate new one */ if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) ) goto Exit; + /* the padding will simply be equal to the `spread' */ + x_shift = 64 * -slot->bitmap_left; + y_shift = 64 * -slot->bitmap_top; + + 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 ) @@ -257,13 +117,8 @@ ft_dense_render( FT_Renderer module, FT_Outline_Translate( outline, x_shift, y_shift ); /* set up parameters */ - params.root.target = bitmap; - params.root.source = outline; - params.root.flags = FT_RASTER_FLAG_DEFAULT; - params.spread = dense_module->spread; - params.flip_sign = dense_module->flip_sign; - params.flip_y = dense_module->flip_y; - params.overlaps = dense_module->overlaps; + params.target = bitmap; + params.source = outline; /* render the outline */ error = @@ -335,7 +190,7 @@ FT_DEFINE_RENDERER( ft_dense_renderer_class, FT_MODULE_RENDERER, - sizeof( DENSE_Renderer_Module ), + sizeof( FT_RendererRec ), "dense", 0x10000L, @@ -345,7 +200,7 @@ FT_DEFINE_RENDERER( (FT_Module_Constructor)ft_dense_init, (FT_Module_Destructor)ft_dense_done, - (FT_Module_Requester)ft_dense_requester, + (FT_Module_Requester)NULL, FT_GLYPH_FORMAT_OUTLINE, diff --git a/src/dense/ftdenserend.h b/src/dense/ftdenserend.h index 7f28eae6d..7c5ae1779 100644 --- a/src/dense/ftdenserend.h +++ b/src/dense/ftdenserend.h @@ -9,66 +9,13 @@ FT_BEGIN_HEADER -/************************************************************************** - * - * @struct: - * DENSE_Renderer_Module - * - * @description: - * This struct extends the native renderer struct `FT_RendererRec`. It - * is basically used to store various parameters required by the - * renderer and some additional parameters that can be used to tweak the - * output of the renderer. - * - * @fields: - * root :: - * The native rendere struct. - * - * spread :: - * This is an essential parameter/property required by the renderer. - * `spread` defines the maximum unsigned value that is present in the - * final SDF output. For the default value check file - * `ftsdfcommon.h`. - * - * flip_sign :: - * By default positive values indicate positions inside of contours, - * i.e., filled by a contour. If this property is true then that - * output will be the opposite of the default, i.e., negative values - * indicate positions inside of contours. - * - * flip_y :: - * Setting this parameter to true makes the output image flipped - * along the y-axis. - * - * overlaps :: - * Set this to true to generate SDF for glyphs having overlapping - * contours. The overlapping support is limited to glyphs that do not - * have self-intersecting contours. Also, removing overlaps require a - * considerable amount of extra memory; additionally, it will not work - * if generating SDF from bitmap. - * - * @note: - * All properties except `overlaps` are valid for both the 'sdf' and - * 'bsdf' renderers. - * - */ -typedef struct DENSE_Renderer_Module_ -{ - FT_RendererRec root; - FT_UInt spread; - FT_Bool flip_sign; - FT_Bool flip_y; - FT_Bool overlaps; - -} DENSE_Renderer_Module, *DENSE_Renderer; - /************************************************************************** * * @renderer: - * ft_sdf_renderer_class + * ft_dense_renderer_class * * @description: - * Renderer to convert @FT_Outline to signed distance fields. + * Renderer to convert @FT_Outline to bitmaps. * */ FT_DECLARE_RENDERER( ft_dense_renderer_class )