diff --git a/data/fontDistanceField/font1.frag b/data/fontDistanceField/font1.frag index 6ac08ec0..dc4d47c1 100644 --- a/data/fontDistanceField/font1.frag +++ b/data/fontDistanceField/font1.frag @@ -15,17 +15,20 @@ 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[3]>0.5) { + /* + if (tmpcolor[0]>0.5) { outColor = f_color; outColor[3] = 1.0; - } else if (tmpcolor[3]>0.49) { + } else if (tmpcolor[0]>0.49) { // antialiasing : outColor = f_color; - outColor[3] = (tmpcolor[3]-0.49)*1.0/0.02; + 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]); @@ -36,8 +39,10 @@ void main(void) { outColor[3] = 0.0; } } + */ //outColor = vec4(0,0,0,0); //outColor[3] = tmpcolor[3]; gl_FragColor = outColor; + //gl_FragColor = tmpcolor; } diff --git a/data/fontDistanceField/font1.prog b/data/fontDistanceField/font1.prog index a34383fc..9098e61b 100644 --- a/data/fontDistanceField/font1.prog +++ b/data/fontDistanceField/font1.prog @@ -1,2 +1,2 @@ -fontDistanceField/font1.vert -fontDistanceField/font1.frag \ No newline at end of file +font1.vert +font1.frag \ No newline at end of file diff --git a/data/fontDistanceField/font1.vert b/data/fontDistanceField/font1.vert index d975573d..1050877b 100644 --- a/data/fontDistanceField/font1.vert +++ b/data/fontDistanceField/font1.vert @@ -4,7 +4,7 @@ precision mediump int; #endif // Input : -attribute vec2 EW_coord2d; +attribute vec3 EW_coord3d; attribute vec2 EW_texture2d; attribute vec4 EW_color; uniform mat4 EW_MatrixTransformation; @@ -14,7 +14,7 @@ varying vec4 f_color; varying vec2 f_texcoord; void main(void) { - gl_Position = EW_MatrixTransformation * vec4(EW_coord2d, 0.0, 1.0); + gl_Position = EW_MatrixTransformation * vec4(EW_coord3d, 1.0); // set texture output coord f_texcoord = EW_texture2d; // set output color : diff --git a/external/edtaa3/edtaa3/edtaa3func.c b/external/edtaa3/edtaa3/edtaa3func.c new file mode 100644 index 00000000..530d6d80 --- /dev/null +++ b/external/edtaa3/edtaa3/edtaa3func.c @@ -0,0 +1,577 @@ +/* + * Copyright 2009 Stefan Gustavson (stefan.gustavson@gmail.com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY STEFAN GUSTAVSON ''AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL STEFAN GUSTAVSON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are + * those of the authors and should not be interpreted as representing official + * policies, either expressed or implied, of Stefan Gustavson. + * + * + * edtaa3() + * + * Sweep-and-update Euclidean distance transform of an + * image. Positive pixels are treated as object pixels, + * zero or negative pixels are treated as background. + * An attempt is made to treat antialiased edges correctly. + * The input image must have pixels in the range [0,1], + * and the antialiased image should be a box-filter + * sampling of the ideal, crisp edge. + * If the antialias region is more than 1 pixel wide, + * the result from this transform will be inaccurate. + * + * By Stefan Gustavson (stefan.gustavson@gmail.com). + * + * Originally written in 1994, based on a verbal + * description of the SSED8 algorithm published in the + * PhD dissertation of Ingemar Ragnemalm. This is his + * algorithm, I only implemented it in C. + * + * Updated in 2004 to treat border pixels correctly, + * and cleaned up the code to improve readability. + * + * Updated in 2009 to handle anti-aliased edges. + * + * Updated in 2011 to avoid a corner case infinite loop. + * +*/ +#include + + +/* + * Compute the local gradient at edge pixels using convolution filters. + * The gradient is computed only at edge pixels. At other places in the + * image, it is never used, and it's mostly zero anyway. + */ +void computegradient(double *img, int w, int h, double *gx, double *gy) +{ + int i,j,k; + double glength; +#define SQRT2 1.4142136 + for(i = 1; i < h-1; i++) { // Avoid edges where the kernels would spill over + for(j = 1; j < w-1; j++) { + k = i*w + j; + 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]; + 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]; + if(glength > 0.0) { // Avoid division by zero + glength = sqrt(glength); + gx[k]=gx[k]/glength; + gy[k]=gy[k]/glength; + } + } + } + } + // 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 + // around the image edge.) 2x2 kernels would be suitable for this. +} + +/* + * A somewhat tricky function to approximate the distance to an edge in a + * certain pixel, with consideration to either the local gradient (gx,gy) + * or the direction to the pixel (dx,dy) and the pixel greyscale value a. + * The latter alternative, using (dx,dy), is the metric used by edtaa2(). + * Using a local estimate of the edge gradient (gx,gy) yields much better + * 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 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 { + glength = sqrt(gx*gx + gy*gy); + if(glength>0) { + 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 + * avoid handling all possible edge directions. + */ + gx = fabs(gx); + gy = fabs(gy); + if(gx 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; + di = sqrt(dx*dx + dy*dy); // Length of integer vector, like a traditional EDT + if(di==0) { // Use local gradient only at edges + // Estimate based on local gradient only + 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() +#define DISTAA(c,xc,yc,xi,yi) (distaa3(img, gx, gy, w, c, xc, yc, xi, yi)) + +void edtaa3(double *img, double *gx, double *gy, int w, int h, short *distx, short *disty, double *dist) +{ + int x, y, i, c; + int offset_u, offset_ur, offset_r, offset_rd, + offset_d, offset_dl, offset_l, offset_lu; + double olddist, newdist; + int cdistx, cdisty, newdistx, newdisty; + int changed; + 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 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) + { + 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) + { + distx[i]=newdistx; + disty[i]=newdisty; + dist[i]=newdist; + changed = 1; + } + } + i++; + + /* Middle pixels have all neighbors */ + for(x=1; x 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) + { + 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) + { + 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) + { + 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--) + { + 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 + + +/* + * Compute the local gradient at edge pixels using convolution filters. + * The gradient is computed only at edge pixels. At other places in the + * image, it is never used, and it's mostly zero anyway. + */ +void computegradient(double *img, int w, int h, double *gx, double *gy); + +/* + * A somewhat tricky function to approximate the distance to an edge in a + * certain pixel, with consideration to either the local gradient (gx,gy) + * or the direction to the pixel (dx,dy) and the pixel greyscale value a. + * The latter alternative, using (dx,dy), is the metric used by edtaa2(). + * Using a local estimate of the edge gradient (gx,gy) yields much better + * 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 distaa3(double *img, double *gximg, double *gyimg, int w, int c, int xc, int yc, int xi, int yi); + +// Shorthand macro: add ubiquitous parameters dist, gx, gy, img and w and call distaa3() +#define DISTAA(c,xc,yc,xi,yi) (distaa3(img, gx, gy, w, c, xc, yc, xi, yi)) + +void edtaa3(double *img, double *gx, double *gy, int w, int h, short *distx, short *disty, double *dist); + + +#ifdef __cplusplus +} +#endif + +#endif // __EDTAA3FUNC_H__ diff --git a/external/edtaa3/license_BSD_2_clauses.txt b/external/edtaa3/license_BSD_2_clauses.txt new file mode 100644 index 00000000..d8a7a616 --- /dev/null +++ b/external/edtaa3/license_BSD_2_clauses.txt @@ -0,0 +1,24 @@ +Copyright 2009 Stefan Gustavson (stefan.gustavson@gmail.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY STEFAN GUSTAVSON ''AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL STEFAN GUSTAVSON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/external/edtaa3/lutin_edtaa3.py b/external/edtaa3/lutin_edtaa3.py new file mode 100644 index 00000000..b0bb0a2a --- /dev/null +++ b/external/edtaa3/lutin_edtaa3.py @@ -0,0 +1,23 @@ +#!/usr/bin/python +import lutinModule as module +import lutinTools as tools +import lutinTools + +def get_desc(): + return "edtaa3 library (create distance field from image)" + +def create(target): + # module name is 'edn' and type binary. + myModule = module.Module(__file__, 'edtaa3', 'LIBRARY') + + # add the file to compile: + myModule.add_src_file([ + 'edtaa3/edtaa3func.c' + ]) + + myModule.add_export_path(tools.get_current_path(__file__)) + + # add the currrent module at the + return myModule + + diff --git a/sources/ewol/resource/DistanceFieldFont.cpp b/sources/ewol/resource/DistanceFieldFont.cpp index 5ea7431a..f7622d76 100644 --- a/sources/ewol/resource/DistanceFieldFont.cpp +++ b/sources/ewol/resource/DistanceFieldFont.cpp @@ -27,7 +27,7 @@ ewol::resource::DistanceFieldFont::DistanceFieldFont(const std::string& _fontNam m_font = NULL; m_lastGlyphPos.setValue(1,1); m_lastRawHeigh = 0; - m_size = 15; + m_size = 36; std::string localName = _fontName; std::vector folderList; if (true == ewol::getContext().getFontDefault().getUseExternal()) { @@ -95,7 +95,7 @@ ewol::resource::DistanceFieldFont::DistanceFieldFont(const std::string& _fontNam } m_height = m_font->getHeight(m_size); // TODO : basic font use 512 is better ... == > maybe estimate it with the dpi ??? - setImageSize(ivec2(512,32)); + setImageSize(ivec2(256,32)); // now we can acces directly on the image m_data.clear(etk::Color<>(0x00000000)); @@ -112,22 +112,106 @@ 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 xdist; + std::vector ydist; + std::vector gx; + std::vector gy; + std::vector data; + std::vector outside; + std::vector 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) + double img_min = 255, img_max = -255; + for(size_t iii = 0; iii < data.size(); ++iii) { + double v = img[iii]; + data[iii] = v; + if (v > img_max) { + img_max = v; + } + if (v < img_min) { + 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; + } + + // 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]); + for(size_t iii = 0; iii < outside.size(); ++iii) { + if( outside[iii] < 0 ) { + outside[iii] = 0.0; + } + } + + // Compute inside = edtaa3(1-bitmap); % Transform foreground (1's) + for(size_t iii = 0; iii < gx.size(); ++iii) { + gx[iii] = 0; + } + for(size_t iii = 0; iii < gy.size(); ++iii) { + gy[iii] = 0; + } + for(size_t iii = 0; iii < data.size(); ++iii) { + 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]); + for(size_t iii = 0; iii < inside.size(); ++iii) { + if( inside[iii] < 0 ) { + inside[iii] = 0.0; + } + } + + _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) { + int32_t iii = yyy * _output.getSize().x() + xxx; + outside[iii] -= inside[iii]; + outside[iii] = 128+outside[iii]*16; + if( outside[iii] < 0 ) { + outside[iii] = 0; + } + if( outside[iii] > 255 ) { + outside[iii] = 255; + } + uint8_t val = 255 - (unsigned char) outside[iii]; + // TODO : Remove multiple size of the map ... + _output.set(ivec2(xxx, yyy), etk::Color<>((int32_t)val,(int32_t)val,(int32_t)val,256)); + } + } +} + class GirdDF { private: std::vector m_data; ivec2 m_size; + ivec2 m_error; public: - GirdDF(const ivec2& _size, const ivec2& _base = ivec2(0,0)) { + 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 { - static const ivec2 error(0, 0); if( _pos.x()>0 && _pos.x()0 && _pos.y()0 && _pos.x()((int32_t)value,(int32_t)value,(int32_t)value,255)); + 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)); } } } @@ -243,25 +327,33 @@ bool ewol::resource::DistanceFieldFont::addGlyph(const char32_t& _val) { } } // draw the glyph - m_font->drawGlyph(imageGlyphRaw, m_size*10, tmpchar); + m_font->drawGlyph(imageGlyphRaw, m_size, tmpchar, 5); GenerateDistanceField(imageGlyphRaw, imageGlyphDistanceField); + if (_val == 'Z') { + for (int32_t yyy = 0; yyy < imageGlyphDistanceField.getSize().y(); ++yyy) { + for (int32_t xxx = 0; xxx < imageGlyphDistanceField.getSize().x(); ++xxx) { + std::cout << (int)(imageGlyphDistanceField.get(ivec2(xxx, yyy)).r()) << " "; + } + //std::cout << std::endl; + } + } m_data.insert(m_lastGlyphPos, imageGlyphDistanceField); // set image position tmpchar.m_texturePosStart.setValue( (float)m_lastGlyphPos.x() / (float)m_data.getSize().x(), (float)m_lastGlyphPos.y() / (float)m_data.getSize().y() ); - tmpchar.m_texturePosSize.setValue( (float)tmpchar.m_sizeTexture.x() / (float)m_data.getSize().x(), - (float)tmpchar.m_sizeTexture.y() / (float)m_data.getSize().y() ); + tmpchar.m_texturePosSize.setValue( (float)imageGlyphRaw.getSize().x() / (float)m_data.getSize().x(), + (float)imageGlyphRaw.getSize().y() / (float)m_data.getSize().y() ); // update the maximum of the line hight : - if (m_lastRawHeigh < tmpchar.m_sizeTexture.y()) { + if (m_lastRawHeigh < imageGlyphRaw.getSize().y()) { // note : +1 is for the overlapping of the glyph (Part 2) - m_lastRawHeigh = tmpchar.m_sizeTexture.y()+1; + m_lastRawHeigh = imageGlyphRaw.getSize().y()+1; } // note : +1 is for the overlapping of the glyph (Part 3) // update the Bitmap position drawing : - m_lastGlyphPos += ivec2(tmpchar.m_sizeTexture.x()+1, 0); + m_lastGlyphPos += ivec2(imageGlyphRaw.getSize().x()+1, 0); } else { EWOL_WARNING("Did not find char : '" << _val << "'=" << _val); tmpchar.setNotExist(); diff --git a/sources/ewol/resource/DistanceFieldFont.h b/sources/ewol/resource/DistanceFieldFont.h index 3bcba48a..d87f0dd3 100644 --- a/sources/ewol/resource/DistanceFieldFont.h +++ b/sources/ewol/resource/DistanceFieldFont.h @@ -86,7 +86,7 @@ namespace ewol { */ bool addGlyph(const char32_t& _val); - void GenerateDistanceField(egami::ImageMono _input, egami::Image _output); + void GenerateDistanceField(const egami::ImageMono& _input, egami::Image& _output); }; }; }; diff --git a/sources/ewol/resource/FontFreeType.cpp b/sources/ewol/resource/FontFreeType.cpp index 0cc7c7a4..3894ac1f 100644 --- a/sources/ewol/resource/FontFreeType.cpp +++ b/sources/ewol/resource/FontFreeType.cpp @@ -224,7 +224,8 @@ bool ewol::resource::FontFreeType::drawGlyph(egami::Image& _imageOut, bool ewol::resource::FontFreeType::drawGlyph(egami::ImageMono& _imageOut, int32_t _fontSize, - ewol::GlyphProperty& _property) { + ewol::GlyphProperty& _property, + int32_t _borderSize) { if(false == m_init) { return false; } @@ -254,13 +255,13 @@ bool ewol::resource::FontFreeType::drawGlyph(egami::ImageMono& _imageOut, return false; } // resize output image : - _imageOut.resize(ivec2(slot->bitmap.width, slot->bitmap.rows), 0); + _imageOut.resize(ivec2(slot->bitmap.width+2*_borderSize, slot->bitmap.rows+2*_borderSize), 0); for(int32_t jjj=0; jjj < slot->bitmap.rows;jjj++) { for(int32_t iii=0; iii < slot->bitmap.width; iii++){ uint8_t valueColor = slot->bitmap.buffer[iii + slot->bitmap.width*jjj]; // real set of color - _imageOut.set(ivec2(iii, jjj), valueColor ); + _imageOut.set(ivec2(_borderSize+iii, _borderSize+jjj), valueColor ); } } return true; diff --git a/sources/ewol/resource/FontFreeType.h b/sources/ewol/resource/FontFreeType.h index bb70f805..3e12ab8e 100644 --- a/sources/ewol/resource/FontFreeType.h +++ b/sources/ewol/resource/FontFreeType.h @@ -44,7 +44,8 @@ namespace ewol { bool drawGlyph(egami::ImageMono& _imageOut, int32_t _fontSize, - ewol::GlyphProperty& _property); + ewol::GlyphProperty& _property, + int32_t _borderSize = 0); vec2 getSize(int32_t _fontSize, const std::string& _unicodeString); diff --git a/sources/ewol/resource/font/FontBase.h b/sources/ewol/resource/font/FontBase.h index b1673354..695d1d44 100644 --- a/sources/ewol/resource/font/FontBase.h +++ b/sources/ewol/resource/font/FontBase.h @@ -37,7 +37,8 @@ namespace ewol { virtual bool drawGlyph(egami::ImageMono& _imageOut, int32_t _fontSize, - ewol::GlyphProperty& _property) = 0; + ewol::GlyphProperty& _property, + int32_t _borderSize = 0) = 0; virtual vec2 getSize(int32_t _fontSize, const std::string& _unicodeString) = 0; diff --git a/sources/lutin_ewol.py b/sources/lutin_ewol.py index 71b69558..09f2045b 100755 --- a/sources/lutin_ewol.py +++ b/sources/lutin_ewol.py @@ -160,9 +160,10 @@ def create(target): myModule.copy_folder('../data/color3.*','') myModule.copy_folder('../data/textured3D2.*','') myModule.copy_folder('../data/textured3D.*','') + myModule.copy_folder('../data/fontDistanceField/*','fontDistanceField') # name of the dependency - myModule.add_module_depend(['etk', 'freetype', 'exml', 'ejson', 'egami', 'date']) + myModule.add_module_depend(['etk', 'freetype', 'exml', 'ejson', 'egami', 'edtaa3', 'date']) myModule.add_export_path(tools.get_current_path(__file__))