[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 vec2 f_texcoord;
|
||||||
varying vec4 f_color;
|
varying vec4 f_color;
|
||||||
|
|
||||||
void main(void) {
|
vec3 glyph_color = vec3(1.0,1.0,1.0);
|
||||||
vec4 tmpcolor = texture2D(EW_texID, f_texcoord);
|
const float glyph_center = 0.50;
|
||||||
vec4 outColor = vec4(0,0,0,0);
|
vec3 outline_color = vec3(0.0,0.0,0.0);
|
||||||
// compare distance with 0.5 that represent the middle ...
|
const float outline_center = 0.55;
|
||||||
/*
|
vec3 glow_color = vec3(1.0,1.0,1.0);
|
||||||
if (tmpcolor[0]>0.5) {
|
const float glow_center = 1.25;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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;
|
f_color = EW_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Distance map contour texturing according to Green (2007),
|
// Distance map contour texturing according to Green (2007),
|
||||||
// implementation by Stefan Gustavson 2009.
|
// implementation by Stefan Gustavson 2009.
|
||||||
|
927
external/edtaa3/edtaa3/edtaa3func.c
vendored
927
external/edtaa3/edtaa3/edtaa3func.c
vendored
@ -5,12 +5,12 @@
|
|||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
*
|
*
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
* this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
*
|
*
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY STEFAN GUSTAVSON ''AS IS'' AND ANY EXPRESS OR
|
* THIS SOFTWARE IS PROVIDED BY STEFAN GUSTAVSON ''AS IS'' AND ANY EXPRESS OR
|
||||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
@ -65,27 +65,27 @@
|
|||||||
*/
|
*/
|
||||||
void computegradient(double *img, int w, int h, double *gx, double *gy)
|
void computegradient(double *img, int w, int h, double *gx, double *gy)
|
||||||
{
|
{
|
||||||
int i,j,k;
|
int i,j,k;
|
||||||
double glength;
|
double glength;
|
||||||
#define SQRT2 1.4142136
|
#define SQRT2 1.4142136
|
||||||
for(i = 1; i < h-1; i++) { // Avoid edges where the kernels would spill over
|
for(i = 1; i < h-1; i++) { // Avoid edges where the kernels would spill over
|
||||||
for(j = 1; j < w-1; j++) {
|
for(j = 1; j < w-1; j++) {
|
||||||
k = i*w + j;
|
k = i*w + j;
|
||||||
if((img[k]>0.0) && (img[k]<1.0)) { // Compute gradient for edge pixels only
|
if((img[k]>0.0) && (img[k]<1.0)) { // Compute gradient for edge pixels only
|
||||||
gx[k] = -img[k-w-1] - SQRT2*img[k-1] - img[k+w-1] + img[k-w+1] + SQRT2*img[k+1] + img[k+w+1];
|
gx[k] = -img[k-w-1] - SQRT2*img[k-1] - img[k+w-1] + img[k-w+1] + SQRT2*img[k+1] + img[k+w+1];
|
||||||
gy[k] = -img[k-w-1] - SQRT2*img[k-w] - img[k+w-1] + img[k-w+1] + SQRT2*img[k+w] + img[k+w+1];
|
gy[k] = -img[k-w-1] - SQRT2*img[k-w] - img[k+w-1] + img[k-w+1] + SQRT2*img[k+w] + img[k+w+1];
|
||||||
glength = gx[k]*gx[k] + gy[k]*gy[k];
|
glength = gx[k]*gx[k] + gy[k]*gy[k];
|
||||||
if(glength > 0.0) { // Avoid division by zero
|
if(glength > 0.0) { // Avoid division by zero
|
||||||
glength = sqrt(glength);
|
glength = sqrt(glength);
|
||||||
gx[k]=gx[k]/glength;
|
gx[k]=gx[k]/glength;
|
||||||
gy[k]=gy[k]/glength;
|
gy[k]=gy[k]/glength;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: Compute reasonable values for gx, gy also around the image edges.
|
// TODO: Compute reasonable values for gx, gy also around the image edges.
|
||||||
// (These are zero now, which reduces the accuracy for a 1-pixel wide region
|
// (These are zero now, which reduces the accuracy for a 1-pixel wide region
|
||||||
// around the image edge.) 2x2 kernels would be suitable for this.
|
// around the image edge.) 2x2 kernels would be suitable for this.
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -97,66 +97,69 @@ 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
|
* accuracy at and near edges, and reduces the error even at distant pixels
|
||||||
* provided that the gradient direction is accurately estimated.
|
* 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;
|
||||||
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
|
||||||
if ((gx == 0) || (gy == 0)) { // Either A) gu or gv are zero, or B) both
|
} else {
|
||||||
df = 0.5-a; // Linear approximation is A) correct or B) a fair guess
|
glength = sqrt(gx*gx + gy*gy);
|
||||||
} else {
|
if(glength>0) {
|
||||||
glength = sqrt(gx*gx + gy*gy);
|
gx = gx/glength;
|
||||||
if(glength>0) {
|
gy = gy/glength;
|
||||||
gx = gx/glength;
|
}
|
||||||
gy = gy/glength;
|
/* Everything is symmetric wrt sign and transposition,
|
||||||
}
|
* so move to first octant (gx>=0, gy>=0, gx>=gy) to
|
||||||
/* Everything is symmetric wrt sign and transposition,
|
* avoid handling all possible edge directions.
|
||||||
* so move to first octant (gx>=0, gy>=0, gx>=gy) to
|
*/
|
||||||
* avoid handling all possible edge directions.
|
gx = fabs(gx);
|
||||||
*/
|
gy = fabs(gy);
|
||||||
gx = fabs(gx);
|
if(gx<gy) {
|
||||||
gy = fabs(gy);
|
temp = gx;
|
||||||
if(gx<gy) {
|
gx = gy;
|
||||||
temp = gx;
|
gy = temp;
|
||||||
gx = gy;
|
}
|
||||||
gy = temp;
|
a1 = 0.5*gy/gx;
|
||||||
}
|
if (a < a1) { // 0 <= a < a1
|
||||||
a1 = 0.5*gy/gx;
|
df = 0.5*(gx + gy) - sqrt(2.0*gx*gy*a);
|
||||||
if (a < a1) { // 0 <= a < a1
|
} else if (a < (1.0-a1)) { // a1 <= a <= 1-a1
|
||||||
df = 0.5*(gx + gy) - sqrt(2.0*gx*gy*a);
|
df = (0.5-a)*gx;
|
||||||
} else if (a < (1.0-a1)) { // a1 <= a <= 1-a1
|
} else { // 1-a1 < a <= 1
|
||||||
df = (0.5-a)*gx;
|
df = -0.5*(gx + gy) + sqrt(2.0*gx*gy*(1.0-a));
|
||||||
} else { // 1-a1 < a <= 1
|
}
|
||||||
df = -0.5*(gx + gy) + sqrt(2.0*gx*gy*(1.0-a));
|
}
|
||||||
}
|
return df;
|
||||||
}
|
|
||||||
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;
|
||||||
double di, df, dx, dy, gx, gy, a;
|
int closest;
|
||||||
int closest;
|
|
||||||
|
closest = c-xc-yc*w; // Index to the edge pixel pointed to from c
|
||||||
closest = c-xc-yc*w; // Index to the edge pixel pointed to from c
|
a = img[closest]; // Grayscale value at the edge pixel
|
||||||
a = img[closest]; // Grayscale value at the edge pixel
|
gx = gximg[closest]; // X gradient component at the edge pixel
|
||||||
gx = gximg[closest]; // X gradient component at the edge pixel
|
gy = gyimg[closest]; // Y gradient component at the edge pixel
|
||||||
gy = gyimg[closest]; // Y gradient component at the edge pixel
|
|
||||||
|
if(a > 1.0) {
|
||||||
if(a > 1.0) 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 < 0.0) {
|
||||||
|
a = 0.0; // Clip grayscale values outside the range [0,1]
|
||||||
dx = (double)xi;
|
}
|
||||||
dy = (double)yi;
|
if(a == 0.0) {
|
||||||
di = sqrt(dx*dx + dy*dy); // Length of integer vector, like a traditional EDT
|
return 1000000.0; // Not an object pixel, return "very far" ("don't know yet")
|
||||||
if(di==0) { // Use local gradient only at edges
|
}
|
||||||
// Estimate based on local gradient only
|
|
||||||
df = edgedf(gx, gy, a);
|
dx = (double)xi;
|
||||||
} else {
|
dy = (double)yi;
|
||||||
// Estimate gradient based on direction to edge (accurate for large di)
|
di = sqrt(dx*dx + dy*dy); // Length of integer vector, like a traditional EDT
|
||||||
df = edgedf(dx, dy, a);
|
if(di==0) { // Use local gradient only at edges
|
||||||
}
|
// Estimate based on local gradient only
|
||||||
return di + df; // Same metric as edtaa2, except at edges (where di=0)
|
df = edgedf(gx, gy, a);
|
||||||
|
} else {
|
||||||
|
// Estimate gradient based on direction to edge (accurate for large di)
|
||||||
|
df = edgedf(dx, dy, a);
|
||||||
|
}
|
||||||
|
return di + df; // Same metric as edtaa2, except at edges (where di=0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shorthand macro: add ubiquitous parameters dist, gx, gy, img and w and call distaa3()
|
// Shorthand macro: add ubiquitous parameters dist, gx, gy, img and w and call distaa3()
|
||||||
@ -164,414 +167,358 @@ double distaa3(double *img, double *gximg, double *gyimg, int w, int c, int xc,
|
|||||||
|
|
||||||
void edtaa3(double *img, double *gx, double *gy, int w, int h, short *distx, short *disty, double *dist)
|
void edtaa3(double *img, double *gx, double *gy, int w, int h, short *distx, short *disty, double *dist)
|
||||||
{
|
{
|
||||||
int x, y, i, c;
|
int x, y, i, c;
|
||||||
int offset_u, offset_ur, offset_r, offset_rd,
|
int offset_u, offset_ur, offset_r, offset_rd,
|
||||||
offset_d, offset_dl, offset_l, offset_lu;
|
offset_d, offset_dl, offset_l, offset_lu;
|
||||||
double olddist, newdist;
|
double olddist, newdist;
|
||||||
int cdistx, cdisty, newdistx, newdisty;
|
int cdistx, cdisty, newdistx, newdisty;
|
||||||
int changed;
|
int changed;
|
||||||
double epsilon = 1e-3;
|
double epsilon = 1e-3;
|
||||||
|
|
||||||
|
/* Initialize index offsets for the current image width */
|
||||||
|
offset_u = -w;
|
||||||
|
offset_ur = -w+1;
|
||||||
|
offset_r = 1;
|
||||||
|
offset_rd = w+1;
|
||||||
|
offset_d = w;
|
||||||
|
offset_dl = w-1;
|
||||||
|
offset_l = -1;
|
||||||
|
offset_lu = -w-1;
|
||||||
|
|
||||||
|
/* Initialize the distance images */
|
||||||
|
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){
|
||||||
|
dist[i]= 1000000.0; // Big value, means "not set yet"
|
||||||
|
} else if (img[i]<1.0) {
|
||||||
|
dist[i] = edgedf(gx[i], gy[i], img[i]); // Gradient-assisted estimate
|
||||||
|
} else {
|
||||||
|
dist[i]= 0.0; // Inside the object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize index offsets for the current image width */
|
/* Perform the transformation */
|
||||||
offset_u = -w;
|
do {
|
||||||
offset_ur = -w+1;
|
changed = 0;
|
||||||
offset_r = 1;
|
|
||||||
offset_rd = w+1;
|
|
||||||
offset_d = w;
|
|
||||||
offset_dl = w-1;
|
|
||||||
offset_l = -1;
|
|
||||||
offset_lu = -w-1;
|
|
||||||
|
|
||||||
/* Initialize the distance images */
|
/* Scan rows, except first row */
|
||||||
for(i=0; i<w*h; i++) {
|
for(y=1; y<h; y++) {
|
||||||
distx[i] = 0; // At first, all pixels point to
|
/* move index to leftmost pixel of current row */
|
||||||
disty[i] = 0; // themselves as the closest known.
|
i = y*w;
|
||||||
if(img[i] <= 0.0)
|
/* scan right, propagate distances from above & left */
|
||||||
{
|
/* Leftmost pixel is special, has no left neighbors */
|
||||||
dist[i]= 1000000.0; // Big value, means "not set yet"
|
olddist = dist[i];
|
||||||
}
|
if(olddist > 0) { // If non-zero distance or not set yet
|
||||||
else if (img[i]<1.0) {
|
c = i + offset_u; // Index of candidate for testing
|
||||||
dist[i] = edgedf(gx[i], gy[i], img[i]); // Gradient-assisted estimate
|
cdistx = distx[c];
|
||||||
}
|
cdisty = disty[c];
|
||||||
else {
|
newdistx = cdistx;
|
||||||
dist[i]= 0.0; // Inside the object
|
newdisty = cdisty+1;
|
||||||
}
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
}
|
if(newdist < olddist-epsilon) {
|
||||||
|
distx[i]=newdistx;
|
||||||
/* Perform the transformation */
|
disty[i]=newdisty;
|
||||||
do
|
dist[i]=newdist;
|
||||||
{
|
olddist=newdist;
|
||||||
changed = 0;
|
changed = 1;
|
||||||
|
}
|
||||||
/* Scan rows, except first row */
|
c = i+offset_ur;
|
||||||
for(y=1; y<h; y++)
|
cdistx = distx[c];
|
||||||
{
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx-1;
|
||||||
/* move index to leftmost pixel of current row */
|
newdisty = cdisty+1;
|
||||||
i = y*w;
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon) {
|
||||||
/* scan right, propagate distances from above & left */
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
/* Leftmost pixel is special, has no left neighbors */
|
dist[i]=newdist;
|
||||||
olddist = dist[i];
|
changed = 1;
|
||||||
if(olddist > 0) // If non-zero distance or not set yet
|
}
|
||||||
{
|
}
|
||||||
c = i + offset_u; // Index of candidate for testing
|
i++;
|
||||||
cdistx = distx[c];
|
/* Middle pixels have all neighbors */
|
||||||
cdisty = disty[c];
|
for(x=1; x<w-1; x++, i++) {
|
||||||
newdistx = cdistx;
|
olddist = dist[i];
|
||||||
newdisty = cdisty+1;
|
if(olddist <= 0) {
|
||||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
continue; // No need to update further
|
||||||
if(newdist < olddist-epsilon)
|
}
|
||||||
{
|
c = i+offset_l;
|
||||||
distx[i]=newdistx;
|
cdistx = distx[c];
|
||||||
disty[i]=newdisty;
|
cdisty = disty[c];
|
||||||
dist[i]=newdist;
|
newdistx = cdistx+1;
|
||||||
olddist=newdist;
|
newdisty = cdisty;
|
||||||
changed = 1;
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
}
|
if(newdist < olddist-epsilon) {
|
||||||
|
distx[i]=newdistx;
|
||||||
c = i+offset_ur;
|
disty[i]=newdisty;
|
||||||
cdistx = distx[c];
|
dist[i]=newdist;
|
||||||
cdisty = disty[c];
|
olddist=newdist;
|
||||||
newdistx = cdistx-1;
|
changed = 1;
|
||||||
newdisty = cdisty+1;
|
}
|
||||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
c = i+offset_lu;
|
||||||
if(newdist < olddist-epsilon)
|
cdistx = distx[c];
|
||||||
{
|
cdisty = disty[c];
|
||||||
distx[i]=newdistx;
|
newdistx = cdistx+1;
|
||||||
disty[i]=newdisty;
|
newdisty = cdisty+1;
|
||||||
dist[i]=newdist;
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
changed = 1;
|
if(newdist < olddist-epsilon) {
|
||||||
}
|
distx[i]=newdistx;
|
||||||
}
|
disty[i]=newdisty;
|
||||||
i++;
|
dist[i]=newdist;
|
||||||
|
olddist=newdist;
|
||||||
/* Middle pixels have all neighbors */
|
changed = 1;
|
||||||
for(x=1; x<w-1; x++, i++)
|
}
|
||||||
{
|
c = i+offset_u;
|
||||||
olddist = dist[i];
|
cdistx = distx[c];
|
||||||
if(olddist <= 0) continue; // No need to update further
|
cdisty = disty[c];
|
||||||
|
newdistx = cdistx;
|
||||||
c = i+offset_l;
|
newdisty = cdisty+1;
|
||||||
cdistx = distx[c];
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
cdisty = disty[c];
|
if(newdist < olddist-epsilon) {
|
||||||
newdistx = cdistx+1;
|
distx[i]=newdistx;
|
||||||
newdisty = cdisty;
|
disty[i]=newdisty;
|
||||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
dist[i]=newdist;
|
||||||
if(newdist < olddist-epsilon)
|
olddist=newdist;
|
||||||
{
|
changed = 1;
|
||||||
distx[i]=newdistx;
|
}
|
||||||
disty[i]=newdisty;
|
c = i+offset_ur;
|
||||||
dist[i]=newdist;
|
cdistx = distx[c];
|
||||||
olddist=newdist;
|
cdisty = disty[c];
|
||||||
changed = 1;
|
newdistx = cdistx-1;
|
||||||
}
|
newdisty = cdisty+1;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
c = i+offset_lu;
|
if(newdist < olddist-epsilon) {
|
||||||
cdistx = distx[c];
|
distx[i]=newdistx;
|
||||||
cdisty = disty[c];
|
disty[i]=newdisty;
|
||||||
newdistx = cdistx+1;
|
dist[i]=newdist;
|
||||||
newdisty = cdisty+1;
|
changed = 1;
|
||||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
}
|
||||||
if(newdist < olddist-epsilon)
|
}
|
||||||
{
|
/* Rightmost pixel of row is special, has no right neighbors */
|
||||||
distx[i]=newdistx;
|
olddist = dist[i];
|
||||||
disty[i]=newdisty;
|
if(olddist > 0) {// If not already zero distance
|
||||||
dist[i]=newdist;
|
c = i+offset_l;
|
||||||
olddist=newdist;
|
cdistx = distx[c];
|
||||||
changed = 1;
|
cdisty = disty[c];
|
||||||
}
|
newdistx = cdistx+1;
|
||||||
|
newdisty = cdisty;
|
||||||
c = i+offset_u;
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
cdistx = distx[c];
|
if(newdist < olddist-epsilon) {
|
||||||
cdisty = disty[c];
|
distx[i]=newdistx;
|
||||||
newdistx = cdistx;
|
disty[i]=newdisty;
|
||||||
newdisty = cdisty+1;
|
dist[i]=newdist;
|
||||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
olddist=newdist;
|
||||||
if(newdist < olddist-epsilon)
|
changed = 1;
|
||||||
{
|
}
|
||||||
distx[i]=newdistx;
|
c = i+offset_lu;
|
||||||
disty[i]=newdisty;
|
cdistx = distx[c];
|
||||||
dist[i]=newdist;
|
cdisty = disty[c];
|
||||||
olddist=newdist;
|
newdistx = cdistx+1;
|
||||||
changed = 1;
|
newdisty = cdisty+1;
|
||||||
}
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
|
if(newdist < olddist-epsilon) {
|
||||||
c = i+offset_ur;
|
distx[i]=newdistx;
|
||||||
cdistx = distx[c];
|
disty[i]=newdisty;
|
||||||
cdisty = disty[c];
|
dist[i]=newdist;
|
||||||
newdistx = cdistx-1;
|
olddist=newdist;
|
||||||
newdisty = cdisty+1;
|
changed = 1;
|
||||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
}
|
||||||
if(newdist < olddist-epsilon)
|
c = i+offset_u;
|
||||||
{
|
cdistx = distx[c];
|
||||||
distx[i]=newdistx;
|
cdisty = disty[c];
|
||||||
disty[i]=newdisty;
|
newdistx = cdistx;
|
||||||
dist[i]=newdist;
|
newdisty = cdisty+1;
|
||||||
changed = 1;
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
}
|
if(newdist < olddist-epsilon) {
|
||||||
}
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
/* Rightmost pixel of row is special, has no right neighbors */
|
dist[i]=newdist;
|
||||||
olddist = dist[i];
|
changed = 1;
|
||||||
if(olddist > 0) // If not already zero distance
|
}
|
||||||
{
|
}
|
||||||
c = i+offset_l;
|
/* Move index to second rightmost pixel of current row. */
|
||||||
cdistx = distx[c];
|
/* Rightmost pixel is skipped, it has no right neighbor. */
|
||||||
cdisty = disty[c];
|
i = y*w + w-2;
|
||||||
newdistx = cdistx+1;
|
/* scan left, propagate distance from right */
|
||||||
newdisty = cdisty;
|
for(x=w-2; x>=0; x--, i--) {
|
||||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
olddist = dist[i];
|
||||||
if(newdist < olddist-epsilon)
|
if(olddist <= 0) {
|
||||||
{
|
continue; // Already zero distance
|
||||||
distx[i]=newdistx;
|
}
|
||||||
disty[i]=newdisty;
|
c = i+offset_r;
|
||||||
dist[i]=newdist;
|
cdistx = distx[c];
|
||||||
olddist=newdist;
|
cdisty = disty[c];
|
||||||
changed = 1;
|
newdistx = cdistx-1;
|
||||||
}
|
newdisty = cdisty;
|
||||||
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
c = i+offset_lu;
|
if(newdist < olddist-epsilon) {
|
||||||
cdistx = distx[c];
|
distx[i]=newdistx;
|
||||||
cdisty = disty[c];
|
disty[i]=newdisty;
|
||||||
newdistx = cdistx+1;
|
dist[i]=newdist;
|
||||||
newdisty = cdisty+1;
|
changed = 1;
|
||||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
}
|
||||||
if(newdist < olddist-epsilon)
|
}
|
||||||
{
|
}
|
||||||
distx[i]=newdistx;
|
/* Scan rows in reverse order, except last row */
|
||||||
disty[i]=newdisty;
|
for(y=h-2; y>=0; y--) {
|
||||||
dist[i]=newdist;
|
/* move index to rightmost pixel of current row */
|
||||||
olddist=newdist;
|
i = y*w + w-1;
|
||||||
changed = 1;
|
/* Scan left, propagate distances from below & right */
|
||||||
}
|
/* Rightmost pixel is special, has no right neighbors */
|
||||||
|
olddist = dist[i];
|
||||||
c = i+offset_u;
|
if(olddist > 0) { // If not already zero distance
|
||||||
cdistx = distx[c];
|
c = i+offset_d;
|
||||||
cdisty = disty[c];
|
cdistx = distx[c];
|
||||||
newdistx = cdistx;
|
cdisty = disty[c];
|
||||||
newdisty = cdisty+1;
|
newdistx = cdistx;
|
||||||
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
newdisty = cdisty-1;
|
||||||
if(newdist < olddist-epsilon)
|
newdist = DISTAA(c, cdistx, cdisty, newdistx, newdisty);
|
||||||
{
|
if(newdist < olddist-epsilon) {
|
||||||
distx[i]=newdistx;
|
distx[i]=newdistx;
|
||||||
disty[i]=newdisty;
|
disty[i]=newdisty;
|
||||||
dist[i]=newdist;
|
dist[i]=newdist;
|
||||||
changed = 1;
|
olddist=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--)
|
|
||||||
{
|
|
||||||
olddist = dist[i];
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
distx[i]=newdistx;
|
|
||||||
disty[i]=newdisty;
|
|
||||||
dist[i]=newdist;
|
|
||||||
changed = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Scan rows in reverse order, except last row */
|
|
||||||
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
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
distx[i]=newdistx;
|
|
||||||
disty[i]=newdisty;
|
|
||||||
dist[i]=newdist;
|
|
||||||
changed = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i--;
|
|
||||||
|
|
||||||
/* Middle pixels have all neighbors */
|
|
||||||
for(x=w-2; x>0; x--, i--)
|
|
||||||
{
|
|
||||||
olddist = dist[i];
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
distx[i]=newdistx;
|
|
||||||
disty[i]=newdisty;
|
|
||||||
dist[i]=newdist;
|
|
||||||
changed = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Leftmost pixel is special, has no left neighbors */
|
|
||||||
olddist = dist[i];
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
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++)
|
|
||||||
{
|
|
||||||
/* scan right, propagate distance from left */
|
|
||||||
olddist = dist[i];
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
distx[i]=newdistx;
|
|
||||||
disty[i]=newdisty;
|
|
||||||
dist[i]=newdist;
|
|
||||||
changed = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(changed); // Sweep until no more updates are made
|
|
||||||
|
|
||||||
/* The transformation is completed. */
|
|
||||||
|
|
||||||
|
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) {
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i--;
|
||||||
|
/* Middle pixels have all neighbors */
|
||||||
|
for(x=w-2; x>0; x--, i--) {
|
||||||
|
olddist = dist[i];
|
||||||
|
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) {
|
||||||
|
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) {
|
||||||
|
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) {
|
||||||
|
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) {
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Leftmost pixel is special, has no left neighbors */
|
||||||
|
olddist = dist[i];
|
||||||
|
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) {
|
||||||
|
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) {
|
||||||
|
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) {
|
||||||
|
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++) {
|
||||||
|
/* scan right, propagate distance from left */
|
||||||
|
olddist = dist[i];
|
||||||
|
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) {
|
||||||
|
distx[i]=newdistx;
|
||||||
|
disty[i]=newdisty;
|
||||||
|
dist[i]=newdist;
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} 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/resource/FontFreeType.h>
|
||||||
#include <ewol/context/Context.h>
|
#include <ewol/context/Context.h>
|
||||||
#include <ewol/resource/DistanceFieldFont.h>
|
#include <ewol/resource/DistanceFieldFont.h>
|
||||||
|
#include <edtaa3/edtaa3func.h>
|
||||||
|
|
||||||
#undef __class__
|
#undef __class__
|
||||||
#define __class__ "resource::DistanceFieldFont"
|
#define __class__ "resource::DistanceFieldFont"
|
||||||
@ -27,7 +28,7 @@ ewol::resource::DistanceFieldFont::DistanceFieldFont(const std::string& _fontNam
|
|||||||
m_font = NULL;
|
m_font = NULL;
|
||||||
m_lastGlyphPos.setValue(1,1);
|
m_lastGlyphPos.setValue(1,1);
|
||||||
m_lastRawHeigh = 0;
|
m_lastRawHeigh = 0;
|
||||||
m_size = 36;
|
m_size = 70;
|
||||||
std::string localName = _fontName;
|
std::string localName = _fontName;
|
||||||
std::vector<std::string> folderList;
|
std::vector<std::string> folderList;
|
||||||
if (true == ewol::getContext().getFontDefault().getUseExternal()) {
|
if (true == ewol::getContext().getFontDefault().getUseExternal()) {
|
||||||
@ -112,45 +113,41 @@ ewol::resource::DistanceFieldFont::~DistanceFieldFont(void) {
|
|||||||
ewol::resource::FontFreeType::release(m_font);
|
ewol::resource::FontFreeType::release(m_font);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ewol::resource::DistanceFieldFont::GenerateSoftDistanceField(const egami::ImageMono& _input, egami::Image& _output) {
|
void ewol::resource::DistanceFieldFont::GenerateDistanceField(const egami::ImageMono& _input, egami::Image& _output) {
|
||||||
unsigned char *img = &_input[0];
|
int32_t size = _input.getSize().x() * _input.getSize().y();
|
||||||
unsigned int width = _input.getSize().x();
|
std::vector<short> xdist(size);
|
||||||
unsigned int height = _input.getSize().y();
|
std::vector<short> ydist(size);
|
||||||
std::vector<short> xdist;
|
std::vector<double> gx(size);
|
||||||
std::vector<short> ydist;
|
std::vector<double> gy(size);
|
||||||
std::vector<double> gx;
|
std::vector<double> data(size);
|
||||||
std::vector<double> gy;
|
std::vector<double> outside(size);
|
||||||
std::vector<double> data;
|
std::vector<double> inside(size);
|
||||||
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);
|
|
||||||
|
|
||||||
// Convert img into double (data)
|
// Convert img into double (data)
|
||||||
double img_min = 255, img_max = -255;
|
double img_min = 255, img_max = -255;
|
||||||
for(size_t iii = 0; iii < data.size(); ++iii) {
|
for (int32_t yyy = 0; yyy < _input.getSize().y(); ++yyy) {
|
||||||
double v = img[iii];
|
for (int32_t xxx = 0; xxx < _input.getSize().x(); ++xxx) {
|
||||||
data[iii] = v;
|
int32_t iii = yyy * _input.getSize().x() + xxx;
|
||||||
if (v > img_max) {
|
double v = _input.get(ivec2(xxx, yyy));
|
||||||
img_max = v;
|
data[iii] = v;
|
||||||
}
|
if (v > img_max) {
|
||||||
if (v < img_min) {
|
img_max = v;
|
||||||
img_min = v;
|
}
|
||||||
|
if (v < img_min) {
|
||||||
|
img_min = v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Rescale image levels between 0 and 1
|
// Rescale image levels between 0 and 1
|
||||||
for(size_t iii = 0; iii < data.size(); ++iii) {
|
for (int32_t yyy = 0; yyy < _input.getSize().y(); ++yyy) {
|
||||||
data[iii] = (img[iii]-img_min)/img_max;
|
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)
|
// Compute outside = edtaa3(bitmap); % Transform background (0's)
|
||||||
computegradient(&data[0], _input.getSize().x(), _input.getSize().y(), &gx[0], &gy[0]);
|
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) {
|
for(size_t iii = 0; iii < outside.size(); ++iii) {
|
||||||
if( outside[iii] < 0 ) {
|
if( outside[iii] < 0 ) {
|
||||||
outside[iii] = 0.0;
|
outside[iii] = 0.0;
|
||||||
@ -168,7 +165,7 @@ void ewol::resource::DistanceFieldFont::GenerateSoftDistanceField(const egami::I
|
|||||||
data[iii] = 1 - data[iii];
|
data[iii] = 1 - data[iii];
|
||||||
}
|
}
|
||||||
computegradient( &data[0], _input.getSize().x(), _input.getSize().y(), &gx[0], &gy[0]);
|
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) {
|
for(size_t iii = 0; iii < inside.size(); ++iii) {
|
||||||
if( inside[iii] < 0 ) {
|
if( inside[iii] < 0 ) {
|
||||||
inside[iii] = 0.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 ewol::resource::DistanceFieldFont::addGlyph(const char32_t& _val) {
|
||||||
bool hasChange = false;
|
bool hasChange = false;
|
||||||
if (m_font == NULL) {
|
if (m_font == NULL) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user