Finish importing code, integration pending

This commit is contained in:
Anurag Thakur 2021-10-29 00:23:34 +05:30
parent 12ffde24a1
commit d019c05e9f
5 changed files with 93 additions and 450 deletions

View File

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

View File

@ -3,11 +3,11 @@
#undef FT_COMPONENT
#define FT_COMPONENT dense
#include "ftdense.h"
#include <freetype/ftoutln.h>
#include <freetype/internal/ftcalc.h>
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftobjs.h>
#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,

View File

@ -7,7 +7,6 @@
#include FT_CONFIG_CONFIG_H
#include <freetype/ftimage.h>
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 );

View File

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

View File

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