forked from minhngoc25a/freetype2
Added commentary
This commit is contained in:
parent
9fd24008ae
commit
b66a91728b
|
@ -1,5 +1,6 @@
|
||||||
/** The rasterizer for the 'dense' renderer */
|
/** The rasterizer for the 'dense' renderer */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#undef FT_COMPONENT
|
#undef FT_COMPONENT
|
||||||
#define FT_COMPONENT dense
|
#define FT_COMPONENT dense
|
||||||
|
|
||||||
|
@ -12,22 +13,25 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "ftdenseerrs.h"
|
#include "ftdenseerrs.h"
|
||||||
|
|
||||||
|
/* @QUES: Please explain all these defines. Why is PIXEL_BITS 8??*/
|
||||||
#define PIXEL_BITS 8
|
#define PIXEL_BITS 8
|
||||||
|
|
||||||
#define ONE_PIXEL ( 1 << PIXEL_BITS )
|
#define ONE_PIXEL ( 1 << PIXEL_BITS )
|
||||||
#define TRUNC( x ) ( int )( ( x ) >> PIXEL_BITS )
|
#define TRUNC( x ) ( int )( ( x ) >> PIXEL_BITS )
|
||||||
#define FRACT( x ) ( int )( ( x ) & ( ONE_PIXEL - 1 ) )
|
|
||||||
|
|
||||||
#define UPSCALE( x ) ( ( x ) * ( ONE_PIXEL >> 6 ) )
|
#define UPSCALE( x ) ( ( x ) * ( ONE_PIXEL >> 6 ) )
|
||||||
#define DOWNSCALE( x ) ( ( x ) >> ( PIXEL_BITS - 6 ) )
|
#define DOWNSCALE( x ) ( ( x ) >> ( PIXEL_BITS - 6 ) )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct dense_TRaster_
|
typedef struct dense_TRaster_
|
||||||
{
|
{
|
||||||
void* memory;
|
void* memory;
|
||||||
|
|
||||||
} dense_TRaster, *dense_PRaster;
|
} dense_TRaster, *dense_PRaster;
|
||||||
|
|
||||||
|
|
||||||
static RasterFP_Point
|
static RasterFP_Point
|
||||||
Lerp( float aT, RasterFP_Point aP0, RasterFP_Point aP1 )
|
Lerp( float aT, RasterFP_Point aP0, RasterFP_Point aP1 )
|
||||||
{
|
{
|
||||||
|
@ -63,11 +67,10 @@ dense_line_to( const FT_Vector* to, RasterFP* aRasterFP )
|
||||||
void
|
void
|
||||||
RasterFP_DrawLine( RasterFP* aRasterFP, RasterFP_Point aP0, RasterFP_Point aP1 )
|
RasterFP_DrawLine( RasterFP* aRasterFP, RasterFP_Point aP0, RasterFP_Point aP1 )
|
||||||
{
|
{
|
||||||
// printf( "\n%f\n", aRasterFP->m_w );
|
|
||||||
// printf( "\n%f\n", aRasterFP->m_h );
|
|
||||||
// assert( aRasterFP );
|
|
||||||
if ( aP0.m_y == aP1.m_y )
|
if ( aP0.m_y == aP1.m_y )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* @QUES: What is this code that I commented out, supposed to do?*/
|
||||||
// aP0.m_x -= aRasterFP->m_origin_x;
|
// aP0.m_x -= aRasterFP->m_origin_x;
|
||||||
// aP0.m_y -= aRasterFP->m_origin_y;
|
// aP0.m_y -= aRasterFP->m_origin_y;
|
||||||
// aP1.m_x -= aRasterFP->m_origin_x;
|
// aP1.m_x -= aRasterFP->m_origin_x;
|
||||||
|
@ -78,9 +81,6 @@ RasterFP_DrawLine( RasterFP* aRasterFP, RasterFP_Point aP0, RasterFP_Point aP1 )
|
||||||
aP1.m_x = TRUNC((int)aP1.m_x );
|
aP1.m_x = TRUNC((int)aP1.m_x );
|
||||||
aP1.m_y = TRUNC((int)aP1.m_y );
|
aP1.m_y = TRUNC((int)aP1.m_y );
|
||||||
|
|
||||||
// printf( "Drawing a line from {%f, %f} to {%f, %f}\n", aP0.m_x, aP0.m_y,
|
|
||||||
// aP1.m_x, aP1.m_y );
|
|
||||||
|
|
||||||
float dir;
|
float dir;
|
||||||
if ( aP0.m_y < aP1.m_y )
|
if ( aP0.m_y < aP1.m_y )
|
||||||
dir = 1;
|
dir = 1;
|
||||||
|
@ -113,6 +113,11 @@ RasterFP_DrawLine( RasterFP* aRasterFP, RasterFP_Point aP0, RasterFP_Point aP1 )
|
||||||
snapping them to the left or right edge, or, if they intersect the clip area,
|
snapping them to the left or right edge, or, if they intersect the clip area,
|
||||||
by recursive calls.
|
by recursive calls.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* @QUES: This code isn't present in font-rs. It was added later by graham asher
|
||||||
|
I have a very strong feeling that this isn't necessary.
|
||||||
|
Since probably the outline is already fitted in the bounding box. I tested
|
||||||
|
this code a little, removing it doesn't seem to make any difference*/
|
||||||
RasterFP_Point intersect = { 0, 0 };
|
RasterFP_Point intersect = { 0, 0 };
|
||||||
int recursive = 0;
|
int recursive = 0;
|
||||||
if ( aP0.m_x >= aRasterFP->m_w && aP1.m_x >= aRasterFP->m_w )
|
if ( aP0.m_x >= aRasterFP->m_w && aP1.m_x >= aRasterFP->m_w )
|
||||||
|
@ -139,7 +144,6 @@ RasterFP_DrawLine( RasterFP* aRasterFP, RasterFP_Point aP0, RasterFP_Point aP1 )
|
||||||
}
|
}
|
||||||
if ( recursive )
|
if ( recursive )
|
||||||
{
|
{
|
||||||
printf("Recursive shit\n");
|
|
||||||
aP0.m_x += aRasterFP->m_origin_x;
|
aP0.m_x += aRasterFP->m_origin_x;
|
||||||
aP0.m_y += aRasterFP->m_origin_y;
|
aP0.m_y += aRasterFP->m_origin_y;
|
||||||
aP1.m_x += aRasterFP->m_origin_x;
|
aP1.m_x += aRasterFP->m_origin_x;
|
||||||
|
@ -159,17 +163,13 @@ RasterFP_DrawLine( RasterFP* aRasterFP, RasterFP_Point aP0, RasterFP_Point aP1 )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* @QUES: I am still trying to understand this code */
|
||||||
float x = aP0.m_x;
|
float x = aP0.m_x;
|
||||||
int y0 = (int)aP0.m_y;
|
int y0 = (int)aP0.m_y;
|
||||||
int y_limit = (int)ceil( aP1.m_y );
|
int y_limit = (int)ceil( aP1.m_y );
|
||||||
float* m_a = aRasterFP->m_a;
|
float* m_a = aRasterFP->m_a;
|
||||||
|
|
||||||
// printf( "%f\n", x );
|
|
||||||
// printf( "%d\n", y0 );
|
|
||||||
// printf( "%d\n", y_limit );
|
|
||||||
// printf( "%p\n", m_a );
|
|
||||||
// printf( "Drawing line from {%f, %f} to {%f, %f}\n", aP0.m_x, aP0.m_y, aP1.m_x,
|
|
||||||
// aP1.m_y );
|
|
||||||
for ( int y = y0; y < y_limit; y++ )
|
for ( int y = y0; y < y_limit; y++ )
|
||||||
{
|
{
|
||||||
int linestart = y * aRasterFP->m_w;
|
int linestart = y * aRasterFP->m_w;
|
||||||
|
@ -354,6 +354,8 @@ RasterFP_DrawCubic( RasterFP* aRasterFP,
|
||||||
RasterFP_DrawLine( aRasterFP, p, aP3 );
|
RasterFP_DrawLine( aRasterFP, p, aP3 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* @QUES: This is the first method called on the module. I suspect
|
||||||
|
this only initializes the memory for it*/
|
||||||
static int
|
static int
|
||||||
dense_raster_new( FT_Memory memory, dense_PRaster* araster )
|
dense_raster_new( FT_Memory memory, dense_PRaster* araster )
|
||||||
{
|
{
|
||||||
|
@ -364,12 +366,16 @@ dense_raster_new( FT_Memory memory, dense_PRaster* araster )
|
||||||
raster->memory = memory;
|
raster->memory = memory;
|
||||||
|
|
||||||
*araster = raster;
|
*araster = raster;
|
||||||
|
printf("dense_raster_new\n");
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* @QUES: This is a simple method, only frees memory*/
|
||||||
static void
|
static void
|
||||||
dense_raster_done( FT_Raster raster )
|
dense_raster_done( FT_Raster raster )
|
||||||
{
|
{
|
||||||
|
printf( "dense_raster_done\n" );
|
||||||
|
|
||||||
FT_Memory memory = (FT_Memory)( (dense_PRaster)raster )->memory;
|
FT_Memory memory = (FT_Memory)( (dense_PRaster)raster )->memory;
|
||||||
|
|
||||||
FT_FREE( raster );
|
FT_FREE( raster );
|
||||||
|
@ -383,8 +389,10 @@ dense_raster_reset( FT_Raster raster,
|
||||||
FT_UNUSED( raster );
|
FT_UNUSED( raster );
|
||||||
FT_UNUSED( pool_base );
|
FT_UNUSED( pool_base );
|
||||||
FT_UNUSED( pool_size );
|
FT_UNUSED( pool_size );
|
||||||
|
printf("dense_raster_reset\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* @QUES: This methodisnt't called in normal ftlint execution*/
|
||||||
static int
|
static int
|
||||||
dense_raster_set_mode( FT_Raster raster, unsigned long mode, void* args )
|
dense_raster_set_mode( FT_Raster raster, unsigned long mode, void* args )
|
||||||
{
|
{
|
||||||
|
@ -392,6 +400,7 @@ dense_raster_set_mode( FT_Raster raster, unsigned long mode, void* args )
|
||||||
FT_UNUSED( mode );
|
FT_UNUSED( mode );
|
||||||
FT_UNUSED( args );
|
FT_UNUSED( args );
|
||||||
|
|
||||||
|
printf("dense_raster_set_mode\n");
|
||||||
return 0; /* nothing to do */
|
return 0; /* nothing to do */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,6 +415,9 @@ FT_DEFINE_OUTLINE_FUNCS( dense_decompose_funcs,
|
||||||
0 /* delta */
|
0 /* delta */
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/* @QUES: So, this calls FT_Outline_Decompose, that calls the move to,
|
||||||
|
line to, conic to, cubic to interface methods. The aRasterFP structure stores the
|
||||||
|
well, stuff in its m_a and finally renders it to the target->buffer*/
|
||||||
static int
|
static int
|
||||||
dense_render_glyph( RasterFP* aRasterFP, const FT_Bitmap* target )
|
dense_render_glyph( RasterFP* aRasterFP, const FT_Bitmap* target )
|
||||||
{
|
{
|
||||||
|
@ -415,12 +427,6 @@ dense_render_glyph( RasterFP* aRasterFP, const FT_Bitmap* target )
|
||||||
const float* source = aRasterFP->m_a;
|
const float* source = aRasterFP->m_a;
|
||||||
|
|
||||||
|
|
||||||
// for (int i = 0; i < aRasterFP->m_h; i++)
|
|
||||||
// {
|
|
||||||
// printf("%f\n", *(source+i));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// printf("pulu %d\n", aRasterFP->m_h);
|
|
||||||
//printf( "Outputting bitmap\n" );
|
//printf( "Outputting bitmap\n" );
|
||||||
// for ( int i = 0; i < aRasterFP->m_h; i++ )
|
// for ( int i = 0; i < aRasterFP->m_h; i++ )
|
||||||
// {
|
// {
|
||||||
|
@ -472,9 +478,13 @@ dense_render_glyph( RasterFP* aRasterFP, const FT_Bitmap* target )
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* @QUES: The main rasterizing method, params.->target->buffer gets the
|
||||||
|
rendered pixels*/
|
||||||
static int
|
static int
|
||||||
dense_raster_render( FT_Raster raster, const FT_Raster_Params* params )
|
dense_raster_render( FT_Raster raster, const FT_Raster_Params* params )
|
||||||
{
|
{
|
||||||
|
printf( "dense_raster_render\n" );
|
||||||
|
|
||||||
const FT_Outline* outline = (const FT_Outline*)params->source;
|
const FT_Outline* outline = (const FT_Outline*)params->source;
|
||||||
const FT_Bitmap* target_map = params->target;
|
const FT_Bitmap* target_map = params->target;
|
||||||
|
|
||||||
|
@ -500,6 +510,7 @@ dense_raster_render( FT_Raster raster, const FT_Raster_Params* params )
|
||||||
|
|
||||||
aRasterFP->m_origin_x = 0;
|
aRasterFP->m_origin_x = 0;
|
||||||
aRasterFP->m_origin_y = 0;
|
aRasterFP->m_origin_y = 0;
|
||||||
|
/* @QUES: Why are my bitmaps upsied down 😭*/
|
||||||
aRasterFP->m_w = target_map->pitch;
|
aRasterFP->m_w = target_map->pitch;
|
||||||
aRasterFP->m_h = target_map->rows;
|
aRasterFP->m_h = target_map->rows;
|
||||||
|
|
||||||
|
|
|
@ -27,34 +27,43 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* @QUES: So, I think this is used for setting up the
|
||||||
|
initial properties of the renderer ??? */
|
||||||
static FT_Error
|
static FT_Error
|
||||||
ft_dense_init( FT_Renderer render )
|
ft_dense_init( FT_Renderer render )
|
||||||
{
|
{
|
||||||
|
printf( "ft_dense_init\n" );
|
||||||
// dense_render->spread = 0;
|
|
||||||
// dense_render->flip_sign = 0;
|
|
||||||
// dense_render->flip_y = 0;
|
|
||||||
// dense_render->overlaps = 0;
|
|
||||||
return FT_Err_Ok;
|
return FT_Err_Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* @QUES: A destructor probably. The smooth renderer doesn't have this
|
||||||
|
so, I guess this is unnecessary ??? */
|
||||||
static void
|
static void
|
||||||
ft_dense_done( FT_Renderer render )
|
ft_dense_done( FT_Renderer render )
|
||||||
{
|
{
|
||||||
|
printf( "ft_dense_done\n" );
|
||||||
FT_UNUSED( render );
|
FT_UNUSED( render );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate bitmap from a glyph's slot image */
|
/* generate bitmap from a glyph's slot image */
|
||||||
|
|
||||||
|
/* @QUES: This method allocates the bitmap buffer, shifts the outlines
|
||||||
|
as required (Why exactly is shifting required?), and finally calls
|
||||||
|
raster_render interface methods with correct params */
|
||||||
static FT_Error
|
static FT_Error
|
||||||
ft_dense_render( FT_Renderer render,
|
ft_dense_render( FT_Renderer render,
|
||||||
FT_GlyphSlot slot,
|
FT_GlyphSlot slot,
|
||||||
FT_Render_Mode mode,
|
FT_Render_Mode mode,
|
||||||
const FT_Vector* origin )
|
const FT_Vector* origin )
|
||||||
{
|
{
|
||||||
|
printf( "ft_dense_render\n" );
|
||||||
FT_Error error = FT_Err_Ok;
|
FT_Error error = FT_Err_Ok;
|
||||||
FT_Outline* outline = &slot->outline;
|
FT_Outline* outline = &slot->outline;
|
||||||
FT_Bitmap* bitmap = &slot->bitmap;
|
FT_Bitmap* bitmap = &slot->bitmap;
|
||||||
FT_Memory memory = NULL;
|
|
||||||
|
/* @QUES: You know, it should be a bit more clear that FT_FREE and FT_ALLOC_MULT macros
|
||||||
|
take a variable named `memory`. It can only be known if you follow the macros 3 level deep.*/
|
||||||
|
FT_Memory memory = render->root.memory;
|
||||||
|
|
||||||
FT_Pos x_shift = 0;
|
FT_Pos x_shift = 0;
|
||||||
FT_Pos y_shift = 0;
|
FT_Pos y_shift = 0;
|
||||||
|
@ -88,20 +97,14 @@ ft_dense_render( FT_Renderer render,
|
||||||
|
|
||||||
|
|
||||||
/* allocate new one */
|
/* allocate new one */
|
||||||
|
if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
// if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) )
|
/* @QUES: Where can I read more about why x and y shift are required */
|
||||||
// goto Exit;
|
|
||||||
|
|
||||||
// For whatever reason, it segfaults if the above is used for allocation
|
|
||||||
bitmap->buffer = realloc(bitmap->buffer, sizeof(int) * bitmap->rows * bitmap->pitch);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* the padding will simply be equal to the `spread' */
|
|
||||||
x_shift = 64 * -slot->bitmap_left;
|
x_shift = 64 * -slot->bitmap_left;
|
||||||
y_shift = 64 * -slot->bitmap_top;
|
y_shift = 64 * -slot->bitmap_top;
|
||||||
|
|
||||||
|
/* @QUES: What does this flag mean ?*/
|
||||||
slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
|
slot->internal->flags |= FT_GLYPH_OWN_BITMAP;
|
||||||
y_shift += 64 * (FT_Int)bitmap->rows;
|
y_shift += 64 * (FT_Int)bitmap->rows;
|
||||||
|
|
||||||
|
@ -119,6 +122,8 @@ ft_dense_render( FT_Renderer render,
|
||||||
params.target = bitmap;
|
params.target = bitmap;
|
||||||
params.source = outline;
|
params.source = outline;
|
||||||
|
|
||||||
|
/* @QUES: Why is my final bitmap upside down ??🤔*/
|
||||||
|
|
||||||
/* render the outline */
|
/* render the outline */
|
||||||
error =
|
error =
|
||||||
render->raster_render( render->raster, (const FT_Raster_Params*)¶ms );
|
render->raster_render( render->raster, (const FT_Raster_Params*)¶ms );
|
||||||
|
@ -142,12 +147,16 @@ Exit:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* transform the glyph using matrix and/or delta */
|
/* transform the glyph using matrix and/or delta */
|
||||||
|
/* @QUES: This mthod isn't called, atleast in normal ftlint execution.
|
||||||
|
What is it for ?*/
|
||||||
static FT_Error
|
static FT_Error
|
||||||
ft_dense_transform( FT_Renderer render,
|
ft_dense_transform( FT_Renderer render,
|
||||||
FT_GlyphSlot slot,
|
FT_GlyphSlot slot,
|
||||||
const FT_Matrix* matrix,
|
const FT_Matrix* matrix,
|
||||||
const FT_Vector* delta )
|
const FT_Vector* delta )
|
||||||
{
|
{
|
||||||
|
printf( "ft_dense_transform\n" );
|
||||||
|
|
||||||
FT_Error error = FT_Err_Ok;
|
FT_Error error = FT_Err_Ok;
|
||||||
|
|
||||||
if ( slot->format != render->glyph_format )
|
if ( slot->format != render->glyph_format )
|
||||||
|
@ -167,9 +176,12 @@ Exit:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return the control box of a glyph's outline */
|
/* return the control box of a glyph's outline */
|
||||||
|
/* @QUES: This method isn't called either in normal ftlint execution*/
|
||||||
static void
|
static void
|
||||||
ft_dense_get_cbox( FT_Renderer render, FT_GlyphSlot slot, FT_BBox* cbox )
|
ft_dense_get_cbox( FT_Renderer render, FT_GlyphSlot slot, FT_BBox* cbox )
|
||||||
{
|
{
|
||||||
|
printf( "ft_dense_get_cbox\n" );
|
||||||
|
|
||||||
FT_ZERO( cbox );
|
FT_ZERO( cbox );
|
||||||
|
|
||||||
if ( slot->format == render->glyph_format )
|
if ( slot->format == render->glyph_format )
|
||||||
|
@ -177,6 +189,7 @@ ft_dense_get_cbox( FT_Renderer render, FT_GlyphSlot slot, FT_BBox* cbox )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set render specific modes or attributes */
|
/* set render specific modes or attributes */
|
||||||
|
/* @QUES: Isn't called in normal ftlint execution*/
|
||||||
static FT_Error
|
static FT_Error
|
||||||
ft_dense_set_mode( FT_Renderer render, FT_ULong mode_tag, FT_Pointer data )
|
ft_dense_set_mode( FT_Renderer render, FT_ULong mode_tag, FT_Pointer data )
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue