summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnuj Verma <anujv@iitbhilai.ac.in>2020-08-20 21:21:33 -0700
committerWerner Lemberg <wl@gnu.org>2020-12-22 09:03:27 +0100
commitf0b6effbe8fe59738d2a361d544c1c6daa49bf78 (patch)
tree7d3c4b84b49d6808881467c20159efac8501f362
parent85b70afc9b98e099612856d3d0c5385e865a6f0f (diff)
downloadfreetype2-f0b6effbe8fe59738d2a361d544c1c6daa49bf78.tar.gz
[sdf] Add function to copy SDF data into output bitmap.
* src/sdf/ftbsdf.c (finalize_sdf): New function.
-rw-r--r--ChangeLog6
-rw-r--r--src/sdf/ftbsdf.c99
2 files changed, 105 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 1503842bb..7fe014ea3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2020-08-20 Anuj Verma <anujv@iitbhilai.ac.in>
+ [sdf] Add function to copy SDF data into output bitmap.
+
+ * src/sdf/ftbsdf.c (finalize_sdf): New function.
+
+2020-08-20 Anuj Verma <anujv@iitbhilai.ac.in>
+
[sdf] Add '8-point sequential Euclidean distance mapping' algorithm.
* src/sdf/ftbsdf.c (compare_neighbor, first_pass, second_pass,
diff --git a/src/sdf/ftbsdf.c b/src/sdf/ftbsdf.c
index aee998790..1ae68fca7 100644
--- a/src/sdf/ftbsdf.c
+++ b/src/sdf/ftbsdf.c
@@ -944,4 +944,103 @@
return error;
}
+
+ /**************************************************************************
+ *
+ * @Function:
+ * finalize_sdf
+ *
+ * @Description:
+ * Copy the SDF data from `worker->distance_map` to the `target` bitmap.
+ * Also transform the data to output format, (which is 6.10 fixed-point
+ * format at the moment).
+ *
+ * @Input:
+ * worker ::
+ * Contains source distance map and other SDF data.
+ *
+ * @Output:
+ * target ::
+ * Target bitmap to which the SDF data is copied to.
+ *
+ * @Return:
+ * 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 */
+ /* its 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 */