summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnuj Verma <anujv@iitbhilai.ac.in>2020-08-01 09:26:22 +0530
committeranujverma <anujv@iitbhilai.ac.in>2020-08-02 16:33:21 +0530
commit77ce541e10c2b553d6d5974b1db40159b49e486f (patch)
tree26a1ccd5a3204b4b91db806a8fc8760c73c18706
parent185c88905e3282b640feb78ccace3a5ebe1adc4e (diff)
downloadfreetype2-77ce541e10c2b553d6d5974b1db40159b49e486f.tar.gz
[sdf -> bsdf] Optimized a bit.
* src/sdf/ftbsdf.c (ED: sign => alpha): Renamed sign to alphs. This is used to store the alpha of the current pixel mapped to the source image. This let's us store additional information without increasing memory usage. * src/sdf/ftbsdf.c (bsdf_init_distance_map): Removed any/all kind of edge approximation and edge check from the function. The function simply copy the source bitmap to the distance map now, preserving alpha values. * src/sdf/ftbsdf.c (compute_edge_distance): Use the new `alpha' parameter to compute gradient and approximate distance. Previously we were using the `dist' variable to store alpha values, which restricts modifying the `dist' variable because we need alpha values of neighbor to compute the gradient. * src/sdf/ftbsdf.c (bsdf_approximate_edge): Now that we can modify the `dist' variable of the distance map, we can combine the two nested loops. * src/sdf/ftbsdf.c (finalize_sdf): Move the `sign' determination and assignment to this function.
-rw-r--r--[GSoC]ChangeLog27
-rw-r--r--src/sdf/ftbsdf.c117
2 files changed, 83 insertions, 61 deletions
diff --git a/[GSoC]ChangeLog b/[GSoC]ChangeLog
index 4570ca395..464e146a0 100644
--- a/[GSoC]ChangeLog
+++ b/[GSoC]ChangeLog
@@ -1,3 +1,30 @@
+2020-08-1 Anuj Verma <anujv@iitbhilai.ac.in>
+
+ [sdf -> bsdf] Optimized a bit.
+
+ * src/sdf/ftbsdf.c (ED: sign => alpha): Renamed sign
+ to alphs. This is used to store the alpha of the current
+ pixel mapped to the source image. This let's us store
+ additional information without increasing memory usage.
+
+ * src/sdf/ftbsdf.c (bsdf_init_distance_map): Removed any/all
+ kind of edge approximation and edge check from the function.
+ The function simply copy the source bitmap to the distance
+ map now, preserving alpha values.
+
+ * src/sdf/ftbsdf.c (compute_edge_distance): Use the new `alpha'
+ parameter to compute gradient and approximate distance.
+ Previously we were using the `dist' variable to store alpha
+ values, which restricts modifying the `dist' variable because
+ we need alpha values of neighbor to compute the gradient.
+
+ * src/sdf/ftbsdf.c (bsdf_approximate_edge): Now that we can
+ modify the `dist' variable of the distance map, we can
+ combine the two nested loops.
+
+ * src/sdf/ftbsdf.c (finalize_sdf): Move the `sign' determination
+ and assignment to this function.
+
2020-07-31 Anuj Verma <anujv@iitbhilai.ac.in>
* src/sdf/ftbsdf.c (compute_edge_distance): Grammer fix.
diff --git a/src/sdf/ftbsdf.c b/src/sdf/ftbsdf.c
index 696d54999..858d538d8 100644
--- a/src/sdf/ftbsdf.c
+++ b/src/sdf/ftbsdf.c
@@ -32,9 +32,9 @@
/* can also be interpreted as edge distance. */
typedef struct ED_
{
- FT_16D16 dist; /* distance at `near' */
- FT_16D16_Vec near; /* nearest point */
- FT_Char sign; /* outside or inside */
+ FT_16D16 dist; /* distance at `near' */
+ FT_16D16_Vec near; /* nearest point */
+ FT_Byte alpha; /* alpha of the source */
} ED;
@@ -208,15 +208,33 @@
/* https://en.wikipedia.org/wiki/Sobel_operator */
/* */
FT_16D16_Vec g = { 0, 0 };
- FT_16D16 dist;
+ FT_16D16 dist, current_alpha;
FT_16D16 a1, temp;
FT_16D16 gx, gy;
+ FT_16D16 alphas[9];
+
+ if ( x == 41 && y == 72 )
+ gx = 0;
+ /* Since our spread cannot be 0, this condition */
+ /* can never be true. */
if ( x <= 0 || x >= w - 1 ||
y <= 0 || y >= r - 1 )
return g;
+ /* initialize the alphas */
+ alphas[0] = 256 * (FT_16D16)current[-w - 1].alpha;
+ alphas[1] = 256 * (FT_16D16)current[ -w ].alpha;
+ alphas[2] = 256 * (FT_16D16)current[-w + 1].alpha;
+ alphas[3] = 256 * (FT_16D16)current[ -1 ].alpha;
+ alphas[4] = 256 * (FT_16D16)current[ 0 ].alpha;
+ alphas[5] = 256 * (FT_16D16)current[ 1 ].alpha;
+ alphas[6] = 256 * (FT_16D16)current[ w - 1].alpha;
+ alphas[7] = 256 * (FT_16D16)current[ w ].alpha;
+ alphas[8] = 256 * (FT_16D16)current[ w + 1].alpha;
+
+ current_alpha = alphas[4];
/* Compute the gradient using the Sobel operator. */
/* In this case we use the following 3x3 filters: */
@@ -230,19 +248,19 @@
/* | 1 root(2) 1 | */
/* */
/* [Note]: 92681 is nothing but root(2) in 16.16 */
- 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.x = -alphas[0] -
+ FT_MulFix( alphas[3], 92681 ) -
+ alphas[6] +
+ alphas[2] +
+ FT_MulFix( alphas[5], 92681 ) +
+ alphas[8];
- 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;
+ g.y = -alphas[0] -
+ FT_MulFix( alphas[1], 92681 ) -
+ alphas[2] +
+ alphas[6] +
+ FT_MulFix( alphas[7], 92681 ) +
+ alphas[8];
FT_Vector_NormLen( &g );
@@ -253,7 +271,7 @@
/* [TODO]: Add squared distance support. */
if ( g.x == 0 || g.y == 0 )
- dist = ONE / 2 - current->dist;
+ dist = ONE / 2 - alphas[4];
else
{
gx = g.x;
@@ -270,16 +288,16 @@
}
a1 = FT_DivFix( gy, gx ) / 2;
- if ( current->dist < a1 )
+ if ( current_alpha < 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 );
+ FT_MulFix( gy, current_alpha ) ) );
+ else if ( current_alpha < ( ONE - a1 ) )
+ dist = FT_MulFix( ONE / 2 - current_alpha, gx );
else
dist = -(( gx + gy ) / 2) +
square_root( 2 * FT_MulFix( gx,
- FT_MulFix( gy, ONE - current->dist ) ) );
+ FT_MulFix( gy, ONE - current_alpha ) ) );
}
g.x = FT_MulFix( g.x, dist );
@@ -325,30 +343,20 @@
{
index = j * worker->width + i;
- if ( ed[index].dist != 0 )
+ /* [TODO]: Check if the current pixel is edge. */
+ if ( ed[index].alpha != 0 )
+ {
/* approximate the edge distance */
ed[index].near = compute_edge_distance( ed + index, i, j,
worker->width, worker->rows );
- }
- }
-
- /* [TODO]: Try to combine the above and below loops. */
- for ( j = 0; j < worker->rows; j++ )
- {
- for ( i = 0; i < worker->width; i++ )
- {
- index = j * worker->width + i;
-
- /* Assign the values, for bacground pixel assign */
- /* values vert far away. */
- if ( ed[index].dist == 0 )
- {
+ ed[index].dist = FT_Vector_Length( &ed[index].near );
+ }
+ else
+ {
ed[index].dist = 200 * ONE;
ed[index].near.x = 100 * ONE;
- ed[index].near.y = 100 * ONE;
+ ed[index].near.y = 100 * ONE;
}
- else
- ed[index].dist = FT_Vector_Length( &ed[index].near );
}
}
@@ -467,7 +475,6 @@
{
FT_Int t_index = t_j * t_width + t_i;
FT_Int s_index;
- FT_Int pixel_value;
t[t_index] = zero_ed;
@@ -479,32 +486,15 @@
/* the source bitmap. */
if ( s_i < 0 || s_i >= s_width ||
s_j < 0 || s_j >= s_rows )
- {
- t[t_index].sign = -1;
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;
- pixel_value = (FT_Int)s[s_index];
-
- /* clamp the pixel value to [0, 256] */
- if ( pixel_value == 255 )
- pixel_value = 256;
-
- /* only assign values to the edge pixels */
- if ( pixel_value )
- t[t_index].dist = 256 * pixel_value;
-
- /* We assume that if the pixel is inside a contour */
- /* then it's coverage value must be > 127. */
- if ( pixel_value > 127 )
- t[t_index].sign = 1;
- else
- t[t_index].sign = -1;
+ /* simply copy the alpha values */
+ t[t_index].alpha = s[s_index];
}
}
@@ -805,6 +795,7 @@
FT_Int index;
FT_16D16 dist;
FT_6D10 final_dist;
+ FT_Char sign;
index = j * w + i;
@@ -818,7 +809,11 @@
if ( final_dist > worker->params.spread * 1024 )
final_dist = worker->params.spread * 1024;
- t_buffer[index] = final_dist * worker->distance_map[index].sign;
+ /* 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;
+
+ t_buffer[index] = final_dist * sign;
}
}