[DEV] better distance field display
This commit is contained in:
parent
d144c0a65f
commit
fbca6c4491
@ -12,37 +12,44 @@ uniform int EW_SoftEdge;
|
||||
varying vec2 f_texcoord;
|
||||
varying vec4 f_color;
|
||||
|
||||
void main(void) {
|
||||
vec4 tmpcolor = texture2D(EW_texID, f_texcoord);
|
||||
vec4 outColor = vec4(0,0,0,0);
|
||||
// compare distance with 0.5 that represent the middle ...
|
||||
/*
|
||||
if (tmpcolor[0]>0.5) {
|
||||
outColor = f_color;
|
||||
outColor[3] = 1.0;
|
||||
} else if (tmpcolor[0]>0.49) {
|
||||
// antialiasing :
|
||||
outColor = f_color;
|
||||
outColor[3] = 0.0;//(tmpcolor[3]-0.49)*1.0/0.02;
|
||||
}
|
||||
*/
|
||||
outColor = f_color;
|
||||
outColor[3] = smoothstep(0.35, 0.65, tmpcolor[0]);
|
||||
/*
|
||||
outColor = f_color;// * tmpcolor[3];
|
||||
if (1==EW_SoftEdge) {
|
||||
outColor[3] = smoothstep(EW_SoftEdgeMin, EW_SoftEdgeMax, tmpcolor[3]);
|
||||
} else {
|
||||
if (tmpcolor[3]>0.5) {
|
||||
outColor[3] = 1.0;
|
||||
} else {
|
||||
outColor[3] = 0.0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
//outColor = vec4(0,0,0,0);
|
||||
//outColor[3] = tmpcolor[3];
|
||||
gl_FragColor = outColor;
|
||||
//gl_FragColor = tmpcolor;
|
||||
}
|
||||
vec3 glyph_color = vec3(1.0,1.0,1.0);
|
||||
const float glyph_center = 0.50;
|
||||
vec3 outline_color = vec3(0.0,0.0,0.0);
|
||||
const float outline_center = 0.55;
|
||||
vec3 glow_color = vec3(1.0,1.0,1.0);
|
||||
const float glow_center = 1.25;
|
||||
|
||||
void main(void) {
|
||||
//vec4 color = texture2D(EW_texID, vec2(int(f_texcoord[0]*256.0)/256.0,int(f_texcoord[1]*256.0)/256.0) );
|
||||
vec4 color = texture2D(EW_texID, f_texcoord );
|
||||
float dist = color.r;
|
||||
float width = fwidth(dist);
|
||||
float alpha = smoothstep(glyph_center-width, glyph_center+width, dist);
|
||||
|
||||
// Smooth
|
||||
|
||||
gl_FragColor = vec4(glyph_color, alpha);
|
||||
|
||||
// Outline
|
||||
/*
|
||||
float mu = smoothstep(outline_center-width, outline_center+width, dist);
|
||||
vec3 rgb = mix(outline_color, glyph_color, mu);
|
||||
gl_FragColor = vec4(rgb, max(alpha,mu));
|
||||
*/
|
||||
// Glow
|
||||
/*
|
||||
vec3 rgb = mix(glow_color, glyph_color, alpha);
|
||||
float mu = smoothstep(glyph_center, glow_center, sqrt(dist));
|
||||
gl_FragColor = vec4(rgb, max(alpha,mu));
|
||||
*/
|
||||
|
||||
// Glow + outline
|
||||
/*
|
||||
vec3 rgb = mix(glow_color, glyph_color, alpha);
|
||||
float mu = smoothstep(glyph_center, glow_center, sqrt(dist));
|
||||
color = vec4(rgb, max(alpha,mu));
|
||||
float beta = smoothstep(outline_center-width, outline_center+width, dist);
|
||||
rgb = mix(outline_color, color.rgb, beta);
|
||||
gl_FragColor = vec4(rgb, max(color.a,beta));
|
||||
*/
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ void main(void) {
|
||||
f_color = EW_color;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Distance map contour texturing according to Green (2007),
|
||||
// implementation by Stefan Gustavson 2009.
|
||||
|
169
external/edtaa3/edtaa3/edtaa3func.c
vendored
169
external/edtaa3/edtaa3/edtaa3func.c
vendored
@ -97,10 +97,8 @@ void computegradient(double *img, int w, int h, double *gx, double *gy)
|
||||
* accuracy at and near edges, and reduces the error even at distant pixels
|
||||
* provided that the gradient direction is accurately estimated.
|
||||
*/
|
||||
double edgedf(double gx, double gy, double a)
|
||||
{
|
||||
double edgedf(double gx, double gy, double a) {
|
||||
double df, glength, temp, a1;
|
||||
|
||||
if ((gx == 0) || (gy == 0)) { // Either A) gu or gv are zero, or B) both
|
||||
df = 0.5-a; // Linear approximation is A) correct or B) a fair guess
|
||||
} else {
|
||||
@ -132,8 +130,7 @@ double edgedf(double gx, double gy, double a)
|
||||
return df;
|
||||
}
|
||||
|
||||
double distaa3(double *img, double *gximg, double *gyimg, int w, int c, int xc, int yc, int xi, int yi)
|
||||
{
|
||||
double distaa3(double *img, double *gximg, double *gyimg, int w, int c, int xc, int yc, int xi, int yi) {
|
||||
double di, df, dx, dy, gx, gy, a;
|
||||
int closest;
|
||||
|
||||
@ -142,9 +139,15 @@ double distaa3(double *img, double *gximg, double *gyimg, int w, int c, int xc,
|
||||
gx = gximg[closest]; // X gradient component at the edge pixel
|
||||
gy = gyimg[closest]; // Y gradient component at the edge pixel
|
||||
|
||||
if(a > 1.0) a = 1.0;
|
||||
if(a < 0.0) a = 0.0; // Clip grayscale values outside the range [0,1]
|
||||
if(a == 0.0) return 1000000.0; // Not an object pixel, return "very far" ("don't know yet")
|
||||
if(a > 1.0) {
|
||||
a = 1.0;
|
||||
}
|
||||
if(a < 0.0) {
|
||||
a = 0.0; // Clip grayscale values outside the range [0,1]
|
||||
}
|
||||
if(a == 0.0) {
|
||||
return 1000000.0; // Not an object pixel, return "very far" ("don't know yet")
|
||||
}
|
||||
|
||||
dx = (double)xi;
|
||||
dy = (double)yi;
|
||||
@ -186,59 +189,47 @@ void edtaa3(double *img, double *gx, double *gy, int w, int h, short *distx, sho
|
||||
for(i=0; i<w*h; i++) {
|
||||
distx[i] = 0; // At first, all pixels point to
|
||||
disty[i] = 0; // themselves as the closest known.
|
||||
if(img[i] <= 0.0)
|
||||
{
|
||||
if(img[i] <= 0.0){
|
||||
dist[i]= 1000000.0; // Big value, means "not set yet"
|
||||
}
|
||||
else if (img[i]<1.0) {
|
||||
} else if (img[i]<1.0) {
|
||||
dist[i] = edgedf(gx[i], gy[i], img[i]); // Gradient-assisted estimate
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
dist[i]= 0.0; // Inside the object
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform the transformation */
|
||||
do
|
||||
{
|
||||
do {
|
||||
changed = 0;
|
||||
|
||||
/* Scan rows, except first row */
|
||||
for(y=1; y<h; y++)
|
||||
{
|
||||
|
||||
for(y=1; y<h; y++) {
|
||||
/* move index to leftmost pixel of current row */
|
||||
i = y*w;
|
||||
|
||||
/* scan right, propagate distances from above & left */
|
||||
|
||||
/* Leftmost pixel is special, has no left neighbors */
|
||||
olddist = dist[i];
|
||||
if(olddist > 0) // If non-zero distance or not set yet
|
||||
{
|
||||
if(olddist > 0) { // If non-zero distance or not set yet
|
||||
c = i + offset_u; // Index of candidate for testing
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx;
|
||||
newdisty = cdisty+1;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
olddist=newdist;
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
c = i+offset_ur;
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx-1;
|
||||
newdisty = cdisty+1;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
@ -246,140 +237,122 @@ void edtaa3(double *img, double *gx, double *gy, int w, int h, short *distx, sho
|
||||
}
|
||||
}
|
||||
i++;
|
||||
|
||||
/* Middle pixels have all neighbors */
|
||||
for(x=1; x<w-1; x++, i++)
|
||||
{
|
||||
for(x=1; x<w-1; x++, i++) {
|
||||
olddist = dist[i];
|
||||
if(olddist <= 0) continue; // No need to update further
|
||||
|
||||
if(olddist <= 0) {
|
||||
continue; // No need to update further
|
||||
}
|
||||
c = i+offset_l;
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx+1;
|
||||
newdisty = cdisty;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
olddist=newdist;
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
c = i+offset_lu;
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx+1;
|
||||
newdisty = cdisty+1;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
olddist=newdist;
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
c = i+offset_u;
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx;
|
||||
newdisty = cdisty+1;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
olddist=newdist;
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
c = i+offset_ur;
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx-1;
|
||||
newdisty = cdisty+1;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
changed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Rightmost pixel of row is special, has no right neighbors */
|
||||
olddist = dist[i];
|
||||
if(olddist > 0) // If not already zero distance
|
||||
{
|
||||
if(olddist > 0) {// If not already zero distance
|
||||
c = i+offset_l;
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx+1;
|
||||
newdisty = cdisty;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
olddist=newdist;
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
c = i+offset_lu;
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx+1;
|
||||
newdisty = cdisty+1;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
olddist=newdist;
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
c = i+offset_u;
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx;
|
||||
newdisty = cdisty+1;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
changed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move index to second rightmost pixel of current row. */
|
||||
/* Rightmost pixel is skipped, it has no right neighbor. */
|
||||
i = y*w + w-2;
|
||||
|
||||
/* scan left, propagate distance from right */
|
||||
for(x=w-2; x>=0; x--, i--)
|
||||
{
|
||||
for(x=w-2; x>=0; x--, i--) {
|
||||
olddist = dist[i];
|
||||
if(olddist <= 0) continue; // Already zero distance
|
||||
|
||||
if(olddist <= 0) {
|
||||
continue; // Already zero distance
|
||||
}
|
||||
c = i+offset_r;
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx-1;
|
||||
newdisty = cdisty;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
@ -387,27 +360,21 @@ void edtaa3(double *img, double *gx, double *gy, int w, int h, short *distx, sho
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Scan rows in reverse order, except last row */
|
||||
for(y=h-2; y>=0; y--)
|
||||
{
|
||||
for(y=h-2; y>=0; y--) {
|
||||
/* move index to rightmost pixel of current row */
|
||||
i = y*w + w-1;
|
||||
|
||||
/* Scan left, propagate distances from below & right */
|
||||
|
||||
/* Rightmost pixel is special, has no right neighbors */
|
||||
olddist = dist[i];
|
||||
if(olddist > 0) // If not already zero distance
|
||||
{
|
||||
if(olddist > 0) { // If not already zero distance
|
||||
c = i+offset_d;
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx;
|
||||
newdisty = cdisty-1;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
@ -421,8 +388,7 @@ void edtaa3(double *img, double *gx, double *gy, int w, int h, short *distx, sho
|
||||
newdistx = cdistx+1;
|
||||
newdisty = cdisty-1;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
@ -430,66 +396,58 @@ void edtaa3(double *img, double *gx, double *gy, int w, int h, short *distx, sho
|
||||
}
|
||||
}
|
||||
i--;
|
||||
|
||||
/* Middle pixels have all neighbors */
|
||||
for(x=w-2; x>0; x--, i--)
|
||||
{
|
||||
for(x=w-2; x>0; x--, i--) {
|
||||
olddist = dist[i];
|
||||
if(olddist <= 0) continue; // Already zero distance
|
||||
|
||||
if(olddist <= 0) {
|
||||
continue; // Already zero distance
|
||||
}
|
||||
c = i+offset_r;
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx-1;
|
||||
newdisty = cdisty;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
olddist=newdist;
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
c = i+offset_rd;
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx-1;
|
||||
newdisty = cdisty-1;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
olddist=newdist;
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
c = i+offset_d;
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx;
|
||||
newdisty = cdisty-1;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
olddist=newdist;
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
c = i+offset_dl;
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx+1;
|
||||
newdisty = cdisty-1;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
@ -498,70 +456,62 @@ void edtaa3(double *img, double *gx, double *gy, int w, int h, short *distx, sho
|
||||
}
|
||||
/* Leftmost pixel is special, has no left neighbors */
|
||||
olddist = dist[i];
|
||||
if(olddist > 0) // If not already zero distance
|
||||
{
|
||||
if(olddist > 0) { // If not already zero distance
|
||||
c = i+offset_r;
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx-1;
|
||||
newdisty = cdisty;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
olddist=newdist;
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
c = i+offset_rd;
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx-1;
|
||||
newdisty = cdisty-1;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
olddist=newdist;
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
c = i+offset_d;
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx;
|
||||
newdisty = cdisty-1;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
changed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move index to second leftmost pixel of current row. */
|
||||
/* Leftmost pixel is skipped, it has no left neighbor. */
|
||||
i = y*w + 1;
|
||||
for(x=1; x<w; x++, i++)
|
||||
{
|
||||
for(x=1; x<w; x++, i++) {
|
||||
/* scan right, propagate distance from left */
|
||||
olddist = dist[i];
|
||||
if(olddist <= 0) continue; // Already zero distance
|
||||
|
||||
if(olddist <= 0) {
|
||||
continue; // Already zero distance
|
||||
}
|
||||
c = i+offset_l;
|
||||
cdistx = distx[c];
|
||||
cdisty = disty[c];
|
||||
newdistx = cdistx+1;
|
||||
newdisty = cdisty;
|
||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||
if(newdist < olddist-epsilon)
|
||||
{
|
||||
if(newdist < olddist-epsilon) {
|
||||
distx[i]=newdistx;
|
||||
disty[i]=newdisty;
|
||||
dist[i]=newdist;
|
||||
@ -569,9 +519,6 @@ void edtaa3(double *img, double *gx, double *gy, int w, int h, short *distx, sho
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while(changed); // Sweep until no more updates are made
|
||||
|
||||
} while(changed); // Sweep until no more updates are made
|
||||
/* The transformation is completed. */
|
||||
|
||||
}
|
||||
|
2
external/etk
vendored
2
external/etk
vendored
@ -1 +1 @@
|
||||
Subproject commit a61639ef292b617a86a07fe30770d8533c17159b
|
||||
Subproject commit b0e3b31664cab066ea3f5e9c42ba6729f40e95e1
|
@ -17,6 +17,7 @@
|
||||
#include <ewol/resource/FontFreeType.h>
|
||||
#include <ewol/context/Context.h>
|
||||
#include <ewol/resource/DistanceFieldFont.h>
|
||||
#include <edtaa3/edtaa3func.h>
|
||||
|
||||
#undef __class__
|
||||
#define __class__ "resource::DistanceFieldFont"
|
||||
@ -27,7 +28,7 @@ ewol::resource::DistanceFieldFont::DistanceFieldFont(const std::string& _fontNam
|
||||
m_font = NULL;
|
||||
m_lastGlyphPos.setValue(1,1);
|
||||
m_lastRawHeigh = 0;
|
||||
m_size = 36;
|
||||
m_size = 70;
|
||||
std::string localName = _fontName;
|
||||
std::vector<std::string> folderList;
|
||||
if (true == ewol::getContext().getFontDefault().getUseExternal()) {
|
||||
@ -112,29 +113,21 @@ ewol::resource::DistanceFieldFont::~DistanceFieldFont(void) {
|
||||
ewol::resource::FontFreeType::release(m_font);
|
||||
}
|
||||
|
||||
void ewol::resource::DistanceFieldFont::GenerateSoftDistanceField(const egami::ImageMono& _input, egami::Image& _output) {
|
||||
unsigned char *img = &_input[0];
|
||||
unsigned int width = _input.getSize().x();
|
||||
unsigned int height = _input.getSize().y();
|
||||
std::vector<short> xdist;
|
||||
std::vector<short> ydist;
|
||||
std::vector<double> gx;
|
||||
std::vector<double> gy;
|
||||
std::vector<double> data;
|
||||
std::vector<double> outside;
|
||||
std::vector<double> inside;
|
||||
xdist.resize(width*height, 0);
|
||||
ydist.resize(width*height, 0);
|
||||
gx.resize(width*height, 0.0);
|
||||
gy.resize(width*height, 0.0);
|
||||
data.resize(width*height, 0.0);
|
||||
outside.resize(width*height, 0.0);
|
||||
inside.resize(width*height, 0.0);
|
||||
|
||||
void ewol::resource::DistanceFieldFont::GenerateDistanceField(const egami::ImageMono& _input, egami::Image& _output) {
|
||||
int32_t size = _input.getSize().x() * _input.getSize().y();
|
||||
std::vector<short> xdist(size);
|
||||
std::vector<short> ydist(size);
|
||||
std::vector<double> gx(size);
|
||||
std::vector<double> gy(size);
|
||||
std::vector<double> data(size);
|
||||
std::vector<double> outside(size);
|
||||
std::vector<double> inside(size);
|
||||
// Convert img into double (data)
|
||||
double img_min = 255, img_max = -255;
|
||||
for(size_t iii = 0; iii < data.size(); ++iii) {
|
||||
double v = img[iii];
|
||||
for (int32_t yyy = 0; yyy < _input.getSize().y(); ++yyy) {
|
||||
for (int32_t xxx = 0; xxx < _input.getSize().x(); ++xxx) {
|
||||
int32_t iii = yyy * _input.getSize().x() + xxx;
|
||||
double v = _input.get(ivec2(xxx, yyy));
|
||||
data[iii] = v;
|
||||
if (v > img_max) {
|
||||
img_max = v;
|
||||
@ -143,14 +136,18 @@ void ewol::resource::DistanceFieldFont::GenerateSoftDistanceField(const egami::I
|
||||
img_min = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Rescale image levels between 0 and 1
|
||||
for(size_t iii = 0; iii < data.size(); ++iii) {
|
||||
data[iii] = (img[iii]-img_min)/img_max;
|
||||
for (int32_t yyy = 0; yyy < _input.getSize().y(); ++yyy) {
|
||||
for (int32_t xxx = 0; xxx < _input.getSize().x(); ++xxx) {
|
||||
int32_t iii = yyy * _input.getSize().x() + xxx;
|
||||
data[iii] = (_input.get(ivec2(xxx, yyy))-img_min)/img_max;
|
||||
}
|
||||
}
|
||||
|
||||
// Compute outside = edtaa3(bitmap); % Transform background (0's)
|
||||
computegradient(&data[0], _input.getSize().x(), _input.getSize().y(), &gx[0], &gy[0]);
|
||||
edtaa3(&data[0], &gx[0], &gy[0], _input.getSize().y(), _input.getSize().x(), &xdist[0], &ydist[0], &outside[0]);
|
||||
edtaa3(&data[0], &gx[0], &gy[0], _input.getSize().x(), _input.getSize().y(), &xdist[0], &ydist[0], &outside[0]);
|
||||
for(size_t iii = 0; iii < outside.size(); ++iii) {
|
||||
if( outside[iii] < 0 ) {
|
||||
outside[iii] = 0.0;
|
||||
@ -168,7 +165,7 @@ void ewol::resource::DistanceFieldFont::GenerateSoftDistanceField(const egami::I
|
||||
data[iii] = 1 - data[iii];
|
||||
}
|
||||
computegradient( &data[0], _input.getSize().x(), _input.getSize().y(), &gx[0], &gy[0]);
|
||||
edtaa3(&data[0], &gx[0], &gy[0], _input.getSize().y(), _input.getSize().x(), &xdist[0], &ydist[0], &inside[0]);
|
||||
edtaa3(&data[0], &gx[0], &gy[0], _input.getSize().x(), _input.getSize().y(), &xdist[0], &ydist[0], &inside[0]);
|
||||
for(size_t iii = 0; iii < inside.size(); ++iii) {
|
||||
if( inside[iii] < 0 ) {
|
||||
inside[iii] = 0.0;
|
||||
@ -195,106 +192,6 @@ void ewol::resource::DistanceFieldFont::GenerateSoftDistanceField(const egami::I
|
||||
}
|
||||
}
|
||||
|
||||
class GirdDF {
|
||||
private:
|
||||
std::vector<ivec2> m_data;
|
||||
ivec2 m_size;
|
||||
ivec2 m_error;
|
||||
public:
|
||||
GirdDF(const ivec2& _size, const ivec2& _base = ivec2(0,0), const ivec2& _error = ivec2(0,0)) {
|
||||
m_size = _size;
|
||||
m_data.resize(m_size.x()*m_size.y(), _base);
|
||||
m_error = _error;
|
||||
}
|
||||
const ivec2& get(const ivec2& _pos) const {
|
||||
if( _pos.x()>0 && _pos.x()<m_size.x()
|
||||
&& _pos.y()>0 && _pos.y()<m_size.y()) {
|
||||
return m_data[_pos.x()+_pos.y()*m_size.x()];
|
||||
}
|
||||
return m_error;
|
||||
}
|
||||
void set(const ivec2& _pos, const ivec2& _data) {
|
||||
if( _pos.x()>0 && _pos.x()<m_size.x()
|
||||
&& _pos.y()>0 && _pos.y()<m_size.y()) {
|
||||
m_data[_pos.x()+_pos.y()*m_size.x()] = _data;
|
||||
}
|
||||
}
|
||||
|
||||
void compare(ivec2& _data, ivec2 _pos, ivec2 _offset) {
|
||||
ivec2 other = get(_pos + _offset) + _offset;
|
||||
if (other.length2() < _data.length2()) {
|
||||
_data = other;
|
||||
}
|
||||
}
|
||||
void GenerateSoftDistanceField(void) {
|
||||
// First pass :
|
||||
for (int32_t yyy = 0; yyy < m_size.y(); ++yyy) {
|
||||
for (int32_t xxx = 0; xxx < m_size.x(); ++xxx) {
|
||||
ivec2 data = get(ivec2(xxx, yyy));
|
||||
compare(data, ivec2(xxx, yyy), ivec2(-1, 0));
|
||||
compare(data, ivec2(xxx, yyy), ivec2( 0, -1));
|
||||
compare(data, ivec2(xxx, yyy), ivec2(-1, -1));
|
||||
compare(data, ivec2(xxx, yyy), ivec2( 1, -1));
|
||||
set(ivec2(xxx, yyy), data);
|
||||
}
|
||||
for (int32_t xxx = m_size.y()-1; xxx >= 0;--xxx) {
|
||||
ivec2 data = get(ivec2(xxx, yyy));
|
||||
compare(data, ivec2(xxx, yyy), ivec2(1, 0));
|
||||
set(ivec2(xxx, yyy), data );
|
||||
}
|
||||
}
|
||||
// Second pass
|
||||
for (int32_t yyy = m_size.y()-1; yyy >= 0; --yyy) {
|
||||
for (int32_t xxx = m_size.x()-1; xxx >= 0; --xxx) {
|
||||
ivec2 data = get(ivec2(xxx, yyy));
|
||||
compare(data, ivec2(xxx, yyy), ivec2( 1, 0));
|
||||
compare(data, ivec2(xxx, yyy), ivec2( 0, 1));
|
||||
compare(data, ivec2(xxx, yyy), ivec2(-1, 1));
|
||||
compare(data, ivec2(xxx, yyy), ivec2( 1, 1));
|
||||
set(ivec2(xxx, yyy), data );
|
||||
}
|
||||
for (int32_t xxx = 0; xxx < m_size.x(); ++xxx) {
|
||||
ivec2 data = get(ivec2(xxx, yyy));
|
||||
compare(data, ivec2(xxx, yyy), ivec2(-1, 0));
|
||||
set(ivec2(xxx, yyy), data);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void ewol::resource::DistanceFieldFont::GenerateDistanceField(const egami::ImageMono& _input, egami::Image& _output) {
|
||||
GirdDF myGird1(_input.getSize(), ivec2(0,0), ivec2(0, 0));
|
||||
GirdDF myGird2(_input.getSize(), ivec2(0,0), ivec2(9999, 9999));
|
||||
|
||||
// Reformat gird :
|
||||
for (int32_t xxx = 0; xxx < _input.getSize().x(); ++xxx) {
|
||||
for (int32_t yyy = 0; yyy < _input.getSize().y(); ++yyy) {
|
||||
if ( _input.get(ivec2(xxx, yyy)) < 128 ) {
|
||||
myGird1.set(ivec2(xxx, yyy), ivec2(0, 0));
|
||||
myGird2.set(ivec2(xxx, yyy), ivec2(9999, 9999));
|
||||
} else {
|
||||
myGird1.set(ivec2(xxx, yyy), ivec2(9999, 9999));
|
||||
myGird2.set(ivec2(xxx, yyy), ivec2(0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Create internal distance of the 2 layer mode :
|
||||
myGird1.GenerateSoftDistanceField();
|
||||
myGird2.GenerateSoftDistanceField();
|
||||
// Generate output :
|
||||
_output.resize(_input.getSize(), etk::Color<>(0));
|
||||
_output.clear(etk::Color<>(0));
|
||||
for (int32_t xxx = 0; xxx < _output.getSize().x(); ++xxx) {
|
||||
for (int32_t yyy = 0; yyy < _output.getSize().y(); ++yyy) {
|
||||
float dist1 = myGird1.get(ivec2(xxx, yyy)).length();
|
||||
float dist2 = myGird2.get(ivec2(xxx, yyy)).length();
|
||||
float dist = dist1 - dist2;
|
||||
float value = etk_avg(0.0f, dist*15.0f + 128.0f, 256.0f);
|
||||
_output.set(ivec2(xxx, yyy), etk::Color<>((int32_t)value,(int32_t)value,(int32_t)value,256));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ewol::resource::DistanceFieldFont::addGlyph(const char32_t& _val) {
|
||||
bool hasChange = false;
|
||||
if (m_font == NULL) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user