[sdf] Add function to copy SDF data into output bitmap. * src/sdf/ftbsdf.c (finalize_sdf): New function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
diff --git a/ChangeLog b/ChangeLog
index 70d4dfe..dc34e2b 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 aee9987..1ae68fc 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 */