diff --git a/src/sdf/ftbsdf.c b/src/sdf/ftbsdf.c index ea2f6f6cc..9a487e284 100644 --- a/src/sdf/ftbsdf.c +++ b/src/sdf/ftbsdf.c @@ -931,4 +931,101 @@ return error; } + /************************************************************************** + * + * @Function: + * finalize_sdf + * + * @Description: + * This function copy the SDF data from `worker->distance_map' to the + * `target' bitmap. It aslo transforms the data to our output format, + * i.e. 6.10 fixed point format at the moment. + * + * @Input: + * worker :: + * Conaints source distance map and parameters/properties which contains + * SDF data. + * + * @Return: + * target :: + * Target bitmap to which the SDF data is copied to. + * + * FT_Error :: + * FreeType error, 0 means success. + * + */ + static FT_Error + finalize_sdf( BSDF_Worker* worker, + const FT_Bitmap* target ) + { + FT_Error error = FT_Err_Ok; + FT_Int w, r; + FT_Int i, j; + FT_6D10* t_buffer; + FT_16D16 spread; + + if ( !worker || !target ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + w = target->width; + r = target->rows; + t_buffer = (FT_6D10*)target->buffer; + + if ( w != worker->width || + r != worker->rows ) + { + error = FT_THROW( Invalid_Argument ); + goto Exit; + } + + #if USE_SQUARED_DISTANCES + spread = FT_INT_16D16( worker->params.spread * + worker->params.spread ); + #else + spread = FT_INT_16D16( worker->params.spread ); + #endif + + for ( j = 0; j < r; j++ ) + { + for ( i = 0; i < w; i++ ) + { + FT_Int index; + FT_16D16 dist; + FT_6D10 final_dist; + FT_Char sign; + + + index = j * w + i; + dist = worker->distance_map[index].dist; + + if ( dist < 0 || dist > spread ) + dist = spread; + + #if USE_SQUARED_DISTANCES + dist = square_root( dist ); + #endif + + /* convert from 16.16 to 6.10 */ + dist /= 64; + final_dist = (FT_6D10)(dist & 0x0000FFFF); + + /* We assume that if the pixel is inside a contour */ + /* then it's coverage value must be > 127. */ + sign = worker->distance_map[index].alpha < 127 ? -1 : 1; + + /* flip the sign according to the property */ + if ( worker->params.flip_sign ) + sign = -sign; + + t_buffer[index] = final_dist * sign; + } + } + + Exit: + return error; + } + /* END */