summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnuj Verma <anujv@iitbhilai.ac.in>2020-08-20 21:09:23 -0700
committerAnuj Verma <anujv@iitbhilai.ac.in>2020-08-20 21:09:23 -0700
commit461d693c29400e322d206474d247b1c2f2692301 (patch)
tree2a28f22a9910883f084e5fc99bae17e76210642b
parente883c6dc5067a360dd0b7ed53f76f32317be8f13 (diff)
downloadfreetype2-461d693c29400e322d206474d247b1c2f2692301.tar.gz
[bsdf] Added function to copy source bitmap to the distance map.
* src/sdf/ftbsdf.c (bsdf_init_distance_map): The function copies the source bitmap to the intermediate distance map which is present within the `worker'.
-rw-r--r--src/sdf/ftbsdf.c190
1 files changed, 190 insertions, 0 deletions
diff --git a/src/sdf/ftbsdf.c b/src/sdf/ftbsdf.c
index ef932f6ad..0cc5b948f 100644
--- a/src/sdf/ftbsdf.c
+++ b/src/sdf/ftbsdf.c
@@ -480,4 +480,194 @@
return error;
}
+ /**************************************************************************
+ *
+ * @Function:
+ * bsdf_init_distance_map
+ *
+ * @Description:
+ * This function initialize the distance map according to
+ * algorithm `8-point sequential Euclidean distance mapping' (8SED).
+ * Basically it copy the `source' bitmap alpha values to the
+ * `distance_map->alpha' parameter of the `worker'.
+ *
+ * @Input:
+ * source ::
+ * Source bitmap to copy the data from.
+ *
+ * @Return:
+ * worker ::
+ * Target distance map to copy the data to.
+ *
+ * FT_Error ::
+ * FreeType error, 0 means success.
+ *
+ */
+ static FT_Error
+ bsdf_init_distance_map( const FT_Bitmap* source,
+ BSDF_Worker* worker )
+ {
+ FT_Error error = FT_Err_Ok;
+
+ FT_Int x_diff, y_diff;
+ FT_Int t_i, t_j, s_i, s_j;
+ FT_Byte* s;
+ ED* t;
+
+ /* again check the parameters (probably unnecessary) */
+ if ( !source || !worker )
+ {
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
+
+ /* Because of the way we convert bitmap to SDF */
+ /* i.e. aligning the source to the center of the */
+ /* target, the target's width/rows must be checked */
+ /* before copying. */
+ if ( worker->width < source->width ||
+ worker->rows < source->rows )
+ {
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
+
+ /* check pixel mode */
+ if ( source->pixel_mode == FT_PIXEL_MODE_NONE )
+ {
+ FT_ERROR(( "[bsdf] bsdf_copy_source_to_target: "
+ "Invalid pixel mode of source bitmap" ));
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
+
+ #ifdef FT_DEBUG_LEVEL_TRACE
+ if ( source->pixel_mode == FT_PIXEL_MODE_MONO )
+ {
+ FT_TRACE0(( "[bsdf] bsdf_copy_source_to_target:\n"
+ "The `bsdf' renderer can convert monochrome bitmap\n"
+ "to SDF, but the results are not perfect because there\n"
+ "is no way to approximate actual outline from monochrome\n"
+ "bitmap. Consider using anti-aliased bitmap instead.\n" ));
+ }
+ #endif
+
+ /* Calculate the difference in width and rows */
+ /* of the target and source. */
+ x_diff = worker->width - source->width;
+ y_diff = worker->rows - source->rows;
+
+ x_diff /= 2;
+ y_diff /= 2;
+
+ t = (ED*)worker->distance_map;
+ s = source->buffer;
+
+ /* For now we only support pixel mode `FT_PIXEL_MODE_MONO' */
+ /* and `FT_PIXEL_MODE_GRAY'. More will be added later. */
+ /* [NOTE]: We can also use `FT_Bitmap_Convert' to convert */
+ /* bitmap to 8bpp. To avoid extra allocation and */
+ /* since the target bitmap can be 16bpp we manually */
+ /* convert the source bitmap to desired bpp. */
+ switch ( source->pixel_mode ) {
+ case FT_PIXEL_MODE_MONO:
+ {
+ FT_Int t_width = worker->width;
+ FT_Int t_rows = worker->rows;
+ FT_Int s_width = source->width;
+ FT_Int s_rows = source->rows;
+
+
+ for ( t_j = 0; t_j < t_rows; t_j++ )
+ {
+ for ( t_i = 0; t_i < t_width; t_i++ )
+ {
+ FT_Int t_index = t_j * t_width + t_i;
+ FT_Int s_index;
+ FT_Int div, mod;
+ FT_Byte pixel, byte;
+
+
+ t[t_index] = zero_ed;
+
+ s_i = t_i - x_diff;
+ s_j = t_j - y_diff;
+
+ /* Assign 0 to padding similar to */
+ /* the source bitmap. */
+ if ( s_i < 0 || s_i >= s_width ||
+ s_j < 0 || s_j >= s_rows )
+ continue;
+
+ if ( worker->params.flip_y )
+ s_index = ( s_rows - s_j - 1 ) * source->pitch;
+ else
+ s_index = s_j * source->pitch;
+
+ div = s_index + s_i / 8;
+ mod = 7 - s_i % 8;
+
+ pixel = s[div];
+ byte = 1 << mod;
+
+ t[t_index].alpha = pixel & byte ? 255 : 0;
+
+ pixel = 0;
+ }
+ }
+ break;
+ }
+ case FT_PIXEL_MODE_GRAY:
+ {
+ FT_Int t_width = worker->width;
+ FT_Int t_rows = worker->rows;
+ FT_Int s_width = source->width;
+ FT_Int s_rows = source->rows;
+
+
+ /* loop through all the pixels and */
+ /* assign pixel values from source */
+ for ( t_j = 0; t_j < t_rows; t_j++ )
+ {
+ for ( t_i = 0; t_i < t_width; t_i++ )
+ {
+ FT_Int t_index = t_j * t_width + t_i;
+ FT_Int s_index;
+
+
+ t[t_index] = zero_ed;
+
+ s_i = t_i - x_diff;
+ s_j = t_j - y_diff;
+
+ /* Assign 0 to padding similar to */
+ /* the source bitmap. */
+ if ( s_i < 0 || s_i >= s_width ||
+ s_j < 0 || s_j >= s_rows )
+ continue;
+
+ if ( worker->params.flip_y )
+ s_index = ( s_rows - s_j - 1 ) * s_width + s_i;
+ else
+ s_index = s_j * s_width + s_i;
+
+ /* simply copy the alpha values */
+ t[t_index].alpha = s[s_index];
+ }
+ }
+
+ break;
+ }
+ default:
+ FT_ERROR(( "[bsdf] bsdf_copy_source_to_target: "
+ "unsopported pixel mode of source bitmap\n" ));
+ error = FT_THROW( Unimplemented_Feature );
+ break;
+ }
+
+ Exit:
+ return error;
+ }
+
+
/* END */