summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnuj Verma <anujv@iitbhilai.ac.in>2020-07-30 16:46:07 +0530
committeranujverma <anujv@iitbhilai.ac.in>2020-08-02 16:33:21 +0530
commitaed19e152448d14116d8acb0f10ea10bc957a828 (patch)
tree5ca39548b80d38bba23c11510fb48259a5970684
parentfbbec7c64d43f20682d6983ad595d470cc73d29f (diff)
downloadfreetype2-aed19e152448d14116d8acb0f10ea10bc957a828.tar.gz
* src/sdf/ftbsdf.c (compute_gradient): Use root(2) for the filter.
Also, use the computed gradient to approximate the edge distance from a pixel's position according to the Gustavson's algorithm.
-rw-r--r--[GSoC]ChangeLog7
-rw-r--r--src/sdf/ftbsdf.c75
2 files changed, 67 insertions, 15 deletions
diff --git a/[GSoC]ChangeLog b/[GSoC]ChangeLog
index edc1a9503..b0232c6d5 100644
--- a/[GSoC]ChangeLog
+++ b/[GSoC]ChangeLog
@@ -1,3 +1,10 @@
+2020-07-30 Anuj Verma <anujv@iitbhilai.ac.in>
+
+ * src/sdf/ftbsdf.c (compute_gradient): Use root(2)
+ for the filter. Also, use the computed gradient
+ to approximate the edge distance from a pixel's
+ position according to the Gustavson's algorithm.
+
2020-07-29 Anuj Verma <anujv@iitbhilai.ac.in>
[sdf -> bsdf] Added function to approximate edge distance.
diff --git a/src/sdf/ftbsdf.c b/src/sdf/ftbsdf.c
index fbde7510a..cdf1406bd 100644
--- a/src/sdf/ftbsdf.c
+++ b/src/sdf/ftbsdf.c
@@ -170,6 +170,9 @@
#undef CHECK_NEIGHBOR
+ static FT_16D16
+ square_root( FT_16D16 val );
+
/**************************************************************************
*
* @Function:
@@ -193,6 +196,9 @@
{
/* [TODO]: Write proper explanation. */
FT_16D16_Vec g = { 0, 0 };
+ FT_16D16 dist;
+ FT_16D16 a1, temp;
+ FT_16D16 gx, gy;
if ( x <= 0 || x >= w - 1 ||
@@ -200,23 +206,61 @@
return g;
- g.x = - current[-w - 1].dist -
- 2 * current[ -1 ].dist -
- current[ w - 1].dist +
- current[-w + 1].dist +
- 2 * current[ 1 ].dist +
- current[ w + 1].dist;
-
- g.y = - current[-w - 1].dist -
- 2 * current[ -w ].dist -
- current[-w + 1].dist +
- current[ w - 1].dist +
- 2 * current[ w ].dist +
- current[ w + 1].dist;
+ /* compute the gradient */
+ g.x = - current[-w - 1].dist -
+ FT_MulFix( current[-1].dist, 92681 ) -
+ current[ w - 1].dist +
+ current[-w + 1].dist +
+ FT_MulFix( current[1].dist, 92681 ) +
+ current[ w + 1].dist;
+
+ g.y = - current[-w - 1].dist -
+ FT_MulFix( current[-w].dist, 92681 ) -
+ current[-w + 1].dist +
+ current[ w - 1].dist +
+ FT_MulFix( current[w].dist, 92681 ) +
+ current[ w + 1].dist;
FT_Vector_NormLen( &g );
- g.x = FT_MulFix( g.x, ONE / 2 - current->dist );
- g.y = FT_MulFix( g.y, ONE / 2 - current->dist );
+
+ /* The gradient gives us the direction of the */
+ /* edge for the current pixel. Once we have the */
+ /* approximate direction of the edge, we can */
+ /* approximate the edge distance much better. */
+
+ /* [TODO]: Add squared distance support. */
+ if ( g.x == 0 || g.y == 0 )
+ dist = ONE / 2 - current->dist;
+ else
+ {
+ gx = g.x;
+ gy = g.y;
+
+ gx = FT_ABS( gx );
+ gy = FT_ABS( gy );
+
+ if ( gx < gy )
+ {
+ temp = gx;
+ gx = gy;
+ gy = temp;
+ }
+
+ a1 = FT_DivFix( gy, gx ) / 2;
+ if ( current->dist < a1 )
+ dist = (( gx + gy ) / 2) -
+ square_root( 2 * FT_MulFix( gx,
+ FT_MulFix( gy, current->dist ) ) );
+ else if ( current->dist < ( ONE - a1 ) )
+ dist = FT_MulFix( ONE / 2 - current->dist, gx );
+ else
+ dist = -(( gx + gy ) / 2) +
+ square_root( 2 * FT_MulFix( gx,
+ FT_MulFix( gy, ONE - current->dist ) ) );
+ }
+
+ g.x = FT_MulFix( g.x, dist );
+ g.y = FT_MulFix( g.y, dist );
return g;
}
@@ -265,6 +309,7 @@
}
}
+ /* [TODO]: Try to combine the above and below loops. */
for ( j = 0; j < worker->rows; j++ )
{
for ( i = 0; i < worker->width; i++ )