diff --git a/[GSoC]ChangeLog b/[GSoC]ChangeLog index c790cbaee..9a1e98250 100644 --- a/[GSoC]ChangeLog +++ b/[GSoC]ChangeLog @@ -1,3 +1,26 @@ +2020-08-1 Anuj Verma + + [sdf -> bsdf] Added option to use squared distances. + + * src/sdf/ftbsdf.c (bsdf_is_edge): Modified the function + to use distance map rather than the alpha values from + the source image. + + * src/sdf/ftbsdf.c (bsdf_approximate_edge): Only calculate + approximate edges for edge pixels. Use `bsdf_is_edge' is + to check for edge pixels. For non edge pixel assgn far + away distances. + + * src/sdf/ftbsdf.c (finalize_sdf): Handle distances in case + of squared distances. + And also use the macro `VECTOR_LENGTH_16D16' in the entire + code to compute vector length. This takes care of squared + distances. + + * src/sdf/ftsdfcommon.c (VECTOR_LENGTH_16D16): Move the macro + `VECTOR_LENGTH_16D16' from `ftsdf.c' to this file because + it is also used by the `bsdf' renderer. + 2020-08-1 Anuj Verma * src/sdf/ftbsdf.c (compare_neighbor): Fix bug. diff --git a/src/sdf/ftbsdf.c b/src/sdf/ftbsdf.c index 73f63dc13..7e4d5e01c 100644 --- a/src/sdf/ftbsdf.c +++ b/src/sdf/ftbsdf.c @@ -74,8 +74,8 @@ y + y_offset >= 0 && y + y_offset < r ) \ { \ num_neighbour++; \ - to_check = s + y_offset * w + x_offset; \ - if ( *to_check == 0 ) \ + to_check = dm + y_offset * w + x_offset; \ + if ( to_check->alpha == 0 ) \ { \ is_edge = 1; \ goto Done; \ @@ -97,21 +97,21 @@ * [TODO] */ static FT_Bool - bsdf_is_edge( FT_Byte* s, /* source bitmap */ + bsdf_is_edge( ED* dm, /* distance map */ FT_Int x, /* x index of point to check */ FT_Int y, /* y index of point to check */ FT_Int w, /* width */ FT_Int r ) /* rows */ { FT_Bool is_edge = 0; - FT_Byte* to_check = NULL; + ED* to_check = NULL; FT_Int num_neighbour = 0; - if ( *s == 0 ) + if ( dm->alpha == 0 ) goto Done; - if ( *s > 0 && *s < 255 ) + if ( dm->alpha > 0 && dm->alpha < 255 ) { is_edge = 1; goto Done; @@ -340,19 +340,20 @@ { index = j * worker->width + i; - /* [TODO]: Check if the current pixel is edge. */ - if ( ed[index].alpha != 0 ) + if ( bsdf_is_edge( worker->distance_map + index, + i, j, worker->width, worker->rows ) ) { - /* approximate the edge distance */ + /* for edge pixels approximate the edge distance */ ed[index].near = compute_edge_distance( ed + index, i, j, worker->width, worker->rows ); - ed[index].dist = FT_Vector_Length( &ed[index].near ); + ed[index].dist = VECTOR_LENGTH_16D16( ed[index].near ); } else { - ed[index].dist = 200 * ONE; - ed[index].near.x = 100 * ONE; - ed[index].near.y = 100 * ONE; + /* for non edge pixels assign far away distances */ + ed[index].dist = 400 * ONE; + ed[index].near.x = 200 * ONE; + ed[index].near.y = 200 * ONE; } } } @@ -554,7 +555,7 @@ dist_vec = to_check->near; dist_vec.x += x_offset * ONE; dist_vec.y += y_offset * ONE; - dist = FT_Vector_Length( &dist_vec ); + dist = VECTOR_LENGTH_16D16( dist_vec ); if ( dist < current->dist ) { current->dist = dist; @@ -798,12 +799,18 @@ index = j * w + i; dist = worker->distance_map[index].dist; + + #if USE_SQUARED_DISTANCES + if ( dist < 0 ) + dist = FT_INT_16D16( worker->params.spread ); + else + dist = square_root( dist ); + #endif + /* convert from 16.16 to 6.10 */ dist /= 64; final_dist = (FT_6D10)(dist & 0x0000FFFF); - /* [TODO]: Assing the sign properly. */ - if ( final_dist > worker->params.spread * 1024 ) final_dist = worker->params.spread * 1024; diff --git a/src/sdf/ftsdf.c b/src/sdf/ftsdf.c index 6a38aedca..bb8b97cb1 100644 --- a/src/sdf/ftsdf.c +++ b/src/sdf/ftsdf.c @@ -155,19 +155,6 @@ #define VEC_26D6_DOT( p, q ) ( MUL_26D6( p.x, q.x ) + \ MUL_26D6( p.y, q.y ) ) - /* [IMPORTANT]: The macro `VECTOR_LENGTH_16D16' is not always the same */ - /* and must not be used anywhere except a few places. This macro is */ - /* controlled by the `USE_SQUARED_DISTANCES' macro. It compute squared */ - /* distance or actual distance based on `USE_SQUARED_DISTANCES' value. */ - /* By using squared distances the performance can be greatly improved */ - /* but there is a risk of overflow. Use it wisely. */ - #if USE_SQUARED_DISTANCES - # define VECTOR_LENGTH_16D16( v ) ( FT_MulFix( v.x, v.x ) + \ - FT_MulFix( v.y, v.y ) ) - #else - # define VECTOR_LENGTH_16D16( v ) FT_Vector_Length( &v ) - #endif - /************************************************************************** * * structures and enums diff --git a/src/sdf/ftsdfcommon.h b/src/sdf/ftsdfcommon.h index 83eb27e23..dec4d4db1 100644 --- a/src/sdf/ftsdfcommon.h +++ b/src/sdf/ftsdfcommon.h @@ -68,6 +68,19 @@ FT_BEGIN_HEADER goto Exit; \ } while ( 0 ) + /* [IMPORTANT]: The macro `VECTOR_LENGTH_16D16' is not always the same */ + /* and must not be used anywhere except a few places. This macro is */ + /* controlled by the `USE_SQUARED_DISTANCES' macro. It compute squared */ + /* distance or actual distance based on `USE_SQUARED_DISTANCES' value. */ + /* By using squared distances the performance can be greatly improved */ + /* but there is a risk of overflow. Use it wisely. */ + #if USE_SQUARED_DISTANCES + # define VECTOR_LENGTH_16D16( v ) ( FT_MulFix( v.x, v.x ) + \ + FT_MulFix( v.y, v.y ) ) + #else + # define VECTOR_LENGTH_16D16( v ) FT_Vector_Length( &v ) + #endif + /************************************************************************** * * common typedefs