[DEV] continue change language

This commit is contained in:
Edouard DUPIN 2021-03-19 23:25:53 +01:00
parent 331cc37de7
commit 4f5a929b2f
16 changed files with 2298 additions and 2177 deletions

View File

@ -48,11 +48,6 @@
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="lib/libfreetype-jni.so">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5">
<attributes>
<attribute name="test" value="true"/>

View File

@ -4,7 +4,21 @@
open module org.atriasoft.ewol {
exports org.atriasoft.ewol;
exports org.atriasoft.ewol.annotation;
exports org.atriasoft.ewol.compositing;
exports org.atriasoft.ewol.compositing.tools;
exports org.atriasoft.ewol.context;
exports org.atriasoft.ewol.event;
exports org.atriasoft.ewol.object;
exports org.atriasoft.ewol.resource;
exports org.atriasoft.ewol.resource.font;
exports org.atriasoft.ewol.tools;
exports org.atriasoft.ewol.widget;
exports org.atriasoft.ewol.widget.meta;
exports org.atriasoft.echrono;
exports org.atriasoft.egami;
exports org.atriasoft.esignal;
requires transitive org.atriasoft.gale;
requires transitive org.atriasoft.etk;

View File

@ -63,6 +63,6 @@ public class DrawProperty {
@Override
public String toString() {
return "DrawProperty [windowsSize=" + this.windowsSize + ", start=" + this.origin + ", stop=" + this.origin.addNew(this.size) + "]";
return "DrawProperty [windowsSize=" + this.windowsSize + ", start=" + this.origin + ", stop=" + this.origin.add(this.size) + "]";
}
}

View File

@ -1,3 +1,5 @@
package org.atriasoft.ewol.compositing;
import org.atriasoft.etk.math.Matrix4f;
import org.atriasoft.etk.math.Vector3f;

View File

@ -8,6 +8,7 @@ package org.atriasoft.ewol.compositing;
import org.atriasoft.egami.Image;
import org.atriasoft.etk.Color;
import org.atriasoft.etk.Uri;
import org.atriasoft.etk.math.FMath;
import org.atriasoft.etk.math.Matrix4f;
import org.atriasoft.etk.math.Vector2f;
import org.atriasoft.etk.math.Vector2i;
@ -116,7 +117,7 @@ class CompositingImage extends Compositing {
OpenGL.enable(OpenGL.Flag.flag_depthTest);
}
// set Matrix : translation/positionMatrix
final Matrix4f tmpMatrix = OpenGL.getMatrix().multiplyNew(this.matrixApply);
final Matrix4f tmpMatrix = OpenGL.getMatrix().multiply(this.matrixApply);
this.GLprogram.use();
this.GLprogram.uniformMatrix(this.GLMatrix, tmpMatrix);
// TextureID
@ -197,7 +198,7 @@ class CompositingImage extends Compositing {
* @param[in] _size size of the output image
*/
public void print(final Vector2i _size) {
print(new Vector2f(_size.x, _size.y));
print(new Vector2f(_size.x(), _size.y()));
};
/**
@ -210,40 +211,36 @@ class CompositingImage extends Compositing {
if (this.resource == null) {
return;
}
final Vector2f openGLSize = new Vector2f(this.resource.getOpenGlSize().x, this.resource.getOpenGlSize().y);
final Vector2f openGLSize = new Vector2f(this.resource.getOpenGlSize().x(), this.resource.getOpenGlSize().y());
final Vector2i usefullSize = this.resource.getUsableSize();
final Vector2f ratio = new Vector2f(usefullSize.x / openGLSize.x, usefullSize.y / openGLSize.y);
final Vector2f sourcePosStart = _sourcePosStart.multiplyNew(ratio);
final Vector2f sourcePosStop = _sourcePosStop.multiplyNew(ratio);
final Vector2f ratio = new Vector2f(usefullSize.x() / openGLSize.x(), usefullSize.y() / openGLSize.y());
final Vector2f sourcePosStart = _sourcePosStart.multiply(ratio);
final Vector2f sourcePosStop = _sourcePosStop.multiply(ratio);
Log.verbose(" openGLSize=" + openGLSize + " usableSize=" + usefullSize + " start=" + sourcePosStart + " stop=" + sourcePosStop);
if (this.angle == 0.0f) {
Vector3f point = this.position.clone();
Vector3f point = this.position;
final Vector3f[] coords = new Vector3f[6];
final Vector2f[] coordsTex = new Vector2f[6];
final Color[] colors = new Color[6];
int indexElem = 0;
Vector2f tex = new Vector2f(sourcePosStart.x, sourcePosStop.y);
Vector2f tex = new Vector2f(sourcePosStart.x(), sourcePosStop.y());
coords[indexElem] = point;
coordsTex[indexElem] = tex;
colors[indexElem] = this.color;
indexElem++;
tex = new Vector2f(sourcePosStop.x, sourcePosStop.y);
point = point.clone();
point.setX(this.position.x + _size.x);
point.setY(this.position.y);
tex = new Vector2f(sourcePosStop.x(), sourcePosStop.y());
point = new Vector3f(this.position.x() + _size.x(), this.position.y(), 0);
coords[indexElem] = point;
coordsTex[indexElem] = tex;
colors[indexElem] = this.color;
indexElem++;
tex = new Vector2f(sourcePosStop.x, sourcePosStart.y);
point = point.clone();
point.setX(this.position.x + _size.x);
point.setY(this.position.y + _size.y);
tex = new Vector2f(sourcePosStop.x(), sourcePosStart.y());
point = new Vector3f(this.position.x() + _size.x(), this.position.y() + _size.y(), 0);
coords[indexElem] = point;
coordsTex[indexElem] = tex;
colors[indexElem] = this.color;
@ -254,19 +251,15 @@ class CompositingImage extends Compositing {
colors[indexElem] = this.color;
indexElem++;
tex = new Vector2f(sourcePosStart.x, sourcePosStart.y);
point = point.clone();
point.setX(this.position.x);
point.setY(this.position.y + _size.y);
tex = new Vector2f(sourcePosStart.x(), sourcePosStart.y());
point = new Vector3f(this.position.x(), this.position.y() + _size.y(), 0);
coords[indexElem] = point;
coordsTex[indexElem] = tex;
colors[indexElem] = this.color;
indexElem++;
tex = new Vector2f(sourcePosStart.x, sourcePosStop.y);
point = point.clone();
point.setX(this.position.x);
point.setY(this.position.y);
tex = new Vector2f(sourcePosStart.x(), sourcePosStop.y());
point = new Vector3f(this.position.x(), this.position.y(), 0);
coords[indexElem] = point;
coordsTex[indexElem] = tex;
colors[indexElem] = this.color;
@ -280,36 +273,36 @@ class CompositingImage extends Compositing {
return;
}
final Vector3f center = this.position.addNew(new Vector3f(_size.x, _size.y, 0)).divide(2.0f);
final Vector3f center = this.position.add(new Vector3f(_size.x(), _size.y(), 0)).divide(2.0f);
final Vector3f limitedSize = new Vector3f(_size.x * 0.5f, _size.y * 0.5f, 0.0f);
final Vector3f limitedSize = new Vector3f(_size.x() * 0.5f, _size.y() * 0.5f, 0.0f);
Vector3f point = new Vector3f(0, 0, 0);
Vector2f tex = new Vector2f(_sourcePosStart.x, sourcePosStop.y);
Vector2f tex = new Vector2f(_sourcePosStart.x(), sourcePosStop.y());
final Vector3f[] coords = new Vector3f[6];
final Vector2f[] coordsTex = new Vector2f[6];
final Color[] colors = new Color[6];
int indexElem = 0;
point = new Vector3f(-limitedSize.x, -limitedSize.y, 0);
point = new Vector3f(-limitedSize.x(), -limitedSize.y(), 0);
point = point.rotateNew(new Vector3f(0, 0, 1), this.angle).add(center);
coords[indexElem] = point;
coordsTex[indexElem] = tex;
colors[indexElem] = this.color;
indexElem++;
tex = new Vector2f(sourcePosStop.x, sourcePosStop.y);
point = new Vector3f(limitedSize.x, -limitedSize.y, 0);
tex = new Vector2f(sourcePosStop.x(), sourcePosStop.y());
point = new Vector3f(limitedSize.x(), -limitedSize.y(), 0);
point = point.rotateNew(new Vector3f(0, 0, 1), this.angle).add(center);
coords[indexElem] = point;
coordsTex[indexElem] = tex;
colors[indexElem] = this.color;
indexElem++;
tex = new Vector2f(sourcePosStop.x, sourcePosStart.y);
point = new Vector3f(limitedSize.x, limitedSize.y, 0);
tex = new Vector2f(sourcePosStop.x(), sourcePosStart.y());
point = new Vector3f(limitedSize.x(), limitedSize.y(), 0);
point = point.rotateNew(new Vector3f(0, 0, 1), this.angle).add(center);
coords[indexElem] = point;
coordsTex[indexElem] = tex;
@ -321,16 +314,16 @@ class CompositingImage extends Compositing {
colors[indexElem] = this.color;
indexElem++;
tex = new Vector2f(sourcePosStart.x, sourcePosStart.y);
point = new Vector3f(-limitedSize.x, limitedSize.y, 0);
tex = new Vector2f(sourcePosStart.x(), sourcePosStart.y());
point = new Vector3f(-limitedSize.x(), limitedSize.y(), 0);
point = point.rotateNew(new Vector3f(0, 0, 1), this.angle).add(center);
coords[indexElem] = point;
coordsTex[indexElem] = tex;
colors[indexElem] = this.color;
indexElem++;
tex = new Vector2f(sourcePosStart.x, sourcePosStop.y);
point = new Vector3f(-limitedSize.x, -limitedSize.y, 0);
tex = new Vector2f(sourcePosStart.x(), sourcePosStop.y());
point = new Vector3f(-limitedSize.x(), -limitedSize.y(), 0);
point = point.rotateNew(new Vector3f(0, 0, 1), this.angle).add(center);
coords[indexElem] = point;
coordsTex[indexElem] = tex;
@ -353,7 +346,7 @@ class CompositingImage extends Compositing {
};
void setClipping(final Vector2f _pos, final Vector2f _posEnd) {
setClipping(new Vector3f(_pos.x, _pos.y, 0), new Vector3f(_posEnd.x, _posEnd.y, 0));
setClipping(new Vector3f(_pos.x(), _pos.y(), 0), new Vector3f(_posEnd.x(), _posEnd.y(), 0));
};
/**
@ -362,28 +355,8 @@ class CompositingImage extends Compositing {
* @param[in] _posEnd End position of the clipping
*/
public void setClipping(final Vector3f _pos, final Vector3f _posEnd) {
// note the internal system all time request to have a bounding all time in the same order
if (_pos.x <= _posEnd.x) {
this.clippingPosStart.setX(_pos.x);
this.clippingPosStop.setX(_posEnd.x);
} else {
this.clippingPosStart.setX(_posEnd.x);
this.clippingPosStop.setX(_pos.x);
}
if (_pos.y <= _posEnd.y) {
this.clippingPosStart.setY(_pos.y);
this.clippingPosStop.setY(_posEnd.y);
} else {
this.clippingPosStart.setY(_posEnd.y);
this.clippingPosStop.setY(_pos.y);
}
if (_pos.z <= _posEnd.z) {
this.clippingPosStart.setZ(_pos.z);
this.clippingPosStop.setZ(_posEnd.z);
} else {
this.clippingPosStart.setZ(_posEnd.z);
this.clippingPosStop.setZ(_pos.z);
}
this.clippingPosStart = FMath.min(_pos, _posEnd);
this.clippingPosStop = FMath.max(_pos, _posEnd);
this.clippingEnable = true;
}
@ -396,7 +369,7 @@ class CompositingImage extends Compositing {
};
public void setClippingWidth(final Vector2f _pos, final Vector2f _width) {
setClippingWidth(new Vector3f(_pos.x, _pos.y, 0), new Vector3f(_width.x, _width.y, 0));
setClippingWidth(new Vector3f(_pos.x(), _pos.y(), 0), new Vector3f(_width.x(), _width.y(), 0));
};
/**
@ -405,7 +378,7 @@ class CompositingImage extends Compositing {
* @param[in] _width Width size of the clipping
*/
public void setClippingWidth(final Vector3f _pos, final Vector3f _width) {
setClipping(_pos, _pos.addNew(_width));
setClipping(_pos, _pos.add(_width));
}
/**
@ -417,7 +390,7 @@ class CompositingImage extends Compositing {
};
public void setPos(final Vector2f _pos) {
setPos(new Vector3f(_pos.x, _pos.y, 0));
setPos(new Vector3f(_pos.x(), _pos.y(), 0));
}
/**
@ -429,7 +402,7 @@ class CompositingImage extends Compositing {
}
public void setRelPos(final Vector2f _pos) {
setRelPos(new Vector3f(_pos.x, _pos.y, 0));
setRelPos(new Vector3f(_pos.x(), _pos.y(), 0));
}
/**
@ -463,7 +436,7 @@ class CompositingImage extends Compositing {
public void setSource(final Uri _uri, final Vector2i _size) {
clear();
if (this.filename == _uri && this.requestSize.x == _size.x && this.requestSize.y == _size.y) {
if (this.filename == _uri && this.requestSize.x() == _size.x() && this.requestSize.y() == _size.y()) {
// Nothing to do ...
return;
}
@ -474,7 +447,7 @@ class CompositingImage extends Compositing {
this.resource = null;
this.resourceImage = null;
final Vector2i tmpSize = new Vector2i(_size.x, _size.y);
final Vector2i tmpSize = new Vector2i(_size.x(), _size.y());
// note that no image can be loaded...
if (_uri.isEmpty() == false) {
// link to new one

View File

@ -0,0 +1,526 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
package org.atriasoft.ewol.compositing;
import java.util.ArrayList;
import java.util.List;
import org.atriasoft.etk.Color;
import org.atriasoft.etk.Uri;
import org.atriasoft.etk.math.FMath;
import org.atriasoft.etk.math.Matrix4f;
import org.atriasoft.etk.math.Vector2f;
import org.atriasoft.etk.math.Vector3f;
import org.atriasoft.ewol.internal.Log;
import org.atriasoft.gale.backend3d.OpenGL;
import org.atriasoft.gale.resource.ResourceProgram;
import org.atriasoft.gale.resource.ResourceVirtualBufferObject;
class Drawing extends Compositing {
protected static int vboIdCoord = 0;
protected static int vboIdColor = 1;
private Vector3f position = new Vector3f(0, 0, 0); // !< The current position to draw
private Vector3f clippingPosStart = new Vector3f(0, 0, 0); // !< Clipping start position
private Vector3f clippingPosStop = new Vector3f(0, 0, 0); // !< Clipping stop position
private boolean clippingEnable = false; // !< true if the clipping must be activated
private Color color = Color.BLACK; // !< The text foreground color
private Color colorBg = Color.NONE; // !< The text background color
private ResourceProgram GLprogram; // !< pointer on the opengl display program
private int GLPosition = -1; // !< openGL id on the element (vertex buffer)
private int GLMatrix = -1; // !< openGL id on the element (transformation matrix)
private int GLMatrixPosition = -1; // !< position matrix
private int GLColor = -1; // !< openGL id on the element (color buffer)
protected ResourceVirtualBufferObject VBO;
private float thickness = 0; // !< when drawing line and other things
private int triElement = 0; // !< special counter of the single dot generated
private final Vector3f[] triangle = new Vector3f[3]; // !< Register every system with a combinaison of tiangle
private final Color[] tricolor = new Color[3]; // !< Register every the associated color foreground
private final List<Vector3f> outTriangles = new ArrayList<>();
private final List<Color> outColors = new ArrayList<>();
// internal API for the generation abstraction of triangles
/**
* @brief Basic ructor
*/
public Drawing() {
loadProgram();
for (int iii = 0; iii < 3; iii++) {
this.triangle[iii] = this.position;
this.tricolor[iii] = this.color;
}
// Create the VBO:
this.VBO = ResourceVirtualBufferObject.create(4);
if (this.VBO == null) {
Log.error("can not instanciate VBO ...");
return;
}
// TO facilitate some debugs we add a name of the VBO:
this.VBO.setName("[VBO] of ewol::compositing::Area");
}
/**
* @brief add a point reference at the current position (this is a vertex
* reference at the current position
*/
public void addVertex() {
internalSetColor(this.color);
setPoint(this.position);
}
/**
* @brief draw a 2D circle with the specify rafdius parameter.
* @param[in] _radius Distence to the dorder
* @param[in] _angleStart start angle of this circle ([0..2PI] otherwithe == >
* disable)
* @param[in] _angleStop stop angle of this circle ([0..2PI] otherwithe == >
* disable)
*/
public void circle(final float _radius) {
circle(_radius, 0);
}
public void circle(final float _radius, final float _angleStart) {
circle(_radius, _angleStart, 2.0f * FMath.PI);
};
public void circle(float _radius, final float _angleStart, float _angleStop) {
resetCount();
if (_radius < 0) {
_radius *= -1;
}
_angleStop = _angleStop - _angleStart;
int nbOcurence = (int) _radius;
if (nbOcurence < 10) {
nbOcurence = 10;
}
// display background :
if (this.colorBg.a() != 0) {
internalSetColor(this.colorBg);
for (int iii = 0; iii < nbOcurence; iii++) {
setPoint(new Vector3f(this.position.x(), this.position.y(), 0));
float angleOne = _angleStart + (_angleStop * iii / nbOcurence);
float offsety = FMath.sin(angleOne) * _radius;
float offsetx = FMath.cos(angleOne) * _radius;
setPoint(new Vector3f(this.position.x() + offsetx, this.position.y() + offsety, 0));
float angleTwo = _angleStart + (_angleStop * (iii + 1) / nbOcurence);
offsety = FMath.sin(angleTwo) * _radius;
offsetx = FMath.cos(angleTwo) * _radius;
setPoint(new Vector3f(this.position.x() + offsetx, this.position.y() + offsety, 0));
}
}
// show if we have a border :
if (this.thickness == 0 || this.color.a() == 0) {
return;
}
internalSetColor(this.color);
for (int iii = 0; iii < nbOcurence; iii++) {
float angleOne = _angleStart + (_angleStop * iii / nbOcurence);
float offsetExty = FMath.sin(angleOne) * (_radius + this.thickness / 2);
float offsetExtx = FMath.cos(angleOne) * (_radius + this.thickness / 2);
float offsetInty = FMath.sin(angleOne) * (_radius - this.thickness / 2);
float offsetIntx = FMath.cos(angleOne) * (_radius - this.thickness / 2);
float angleTwo = _angleStart + (_angleStop * (iii + 1) / nbOcurence);
float offsetExt2y = FMath.sin(angleTwo) * (_radius + this.thickness / 2);
float offsetExt2x = FMath.cos(angleTwo) * (_radius + this.thickness / 2);
float offsetInt2y = FMath.sin(angleTwo) * (_radius - this.thickness / 2);
float offsetInt2x = FMath.cos(angleTwo) * (_radius - this.thickness / 2);
setPoint(new Vector3f(this.position.x() + offsetIntx, this.position.y() + offsetInty, 0));
setPoint(new Vector3f(this.position.x() + offsetExtx, this.position.y() + offsetExty, 0));
setPoint(new Vector3f(this.position.x() + offsetExt2x, this.position.y() + offsetExt2y, 0));
setPoint(new Vector3f(this.position.x() + offsetExt2x, this.position.y() + offsetExt2y, 0));
setPoint(new Vector3f(this.position.x() + offsetInt2x, this.position.y() + offsetInt2y, 0));
setPoint(new Vector3f(this.position.x() + offsetIntx, this.position.y() + offsetInty, 0));
}
}
/**
* @brief clear alll tre registered element in the current element
*/
@Override
public void clear() {
// call upper class
super.clear();
// reset Buffer :
this.VBO.clear();
this.outTriangles.clear();
this.outColors.clear();
// reset temporal variables :
this.position = Vector3f.ZERO;
this.clippingPosStart = Vector3f.ZERO;
this.clippingPosStop = Vector3f.ZERO;
this.clippingEnable = false;
this.color = Color.BLACK;
this.colorBg = Color.NONE;
for (int iii = 0; iii < 3; iii++) {
this.triangle[iii] = this.position;
this.tricolor[iii] = this.color;
}
}
/**
* @brief draw All the refistered text in the current element on openGL
*/
@Override
public void draw(final boolean _disableDepthTest) {
// push data on the VBO
// TODO optimize this with single push when needed
this.VBO.setVboData(Drawing.vboIdCoord, this.outTriangles.toArray(Vector3f[]::new));
this.VBO.setVboData(Drawing.vboIdColor, this.outColors.toArray(Color[]::new));
this.VBO.flush();
if (this.GLprogram == null) {
Log.error("No shader ...");
return;
}
// set Matrix : translation/positionMatrix
Matrix4f tmpMatrix = OpenGL.getMatrix().multiplyNew(this.matrixApply);
this.GLprogram.use();
this.GLprogram.uniformMatrix(this.GLMatrix, tmpMatrix);
this.GLprogram.uniformMatrix(this.GLMatrixPosition, Matrix4f.identity());
// position:
this.GLprogram.sendAttributePointer(this.GLPosition, this.VBO, Drawing.vboIdCoord);
// color:
this.GLprogram.sendAttributePointer(this.GLColor, this.VBO, Drawing.vboIdColor);
// Request the draw od the elements :
OpenGL.drawArrays(OpenGL.RenderMode.triangle, 0, this.VBO.bufferSize(Drawing.vboIdCoord));
this.GLprogram.unUse();
}
/**
* @brief Lunch the generation of triangle
*/
private void generateTriangle() {
this.triElement = 0;
this.outTriangles.add(this.triangle[0]);
this.outTriangles.add(this.triangle[1]);
this.outTriangles.add(this.triangle[2]);
this.outColors.add(this.tricolor[0]);
this.outColors.add(this.tricolor[1]);
this.outColors.add(this.tricolor[2]);
}
/**
* @brief Get the foreground color of the font.
* @return Foreground color.
*/
public Color getColor() {
return this.color;
}
/**
* @brief Get the background color of the font.
* @return Background color.
*/
public Color getColorBg() {
return this.colorBg;
};
/**
* @brief get the current display position (sometime needed in the gui control)
* @return the current position.
*/
public Vector3f getPos() {
return this.position;
};
/**
* @brief set the Color of the current triangle drawing
* @param[in] _color Color to current dots generated
*/
private void internalSetColor(final Color _color) {
if (this.triElement < 1) {
this.tricolor[0] = _color;
}
if (this.triElement < 2) {
this.tricolor[1] = _color;
}
if (this.triElement < 3) {
this.tricolor[2] = _color;
}
};
public void lineRel(final Vector2f _vect) {
lineRel(new Vector3f(_vect.x(), _vect.y(), 0));
};
/**
* @brief Relative drawing a line (spacial vector)
* @param[in] _vect Vector of the curent line.
*/
public void lineRel(final Vector3f _vect) {
lineTo(this.position.add(_vect));
};
public void lineTo(final Vector2f _dest) {
lineTo(new Vector3f(_dest.x(), _dest.y(), 0));
};
/**
* @brief draw a line to a specific position
* @param[in] _dest Position of the end of the line.
*/
public void lineTo(final Vector3f _dest) {
resetCount();
internalSetColor(this.color);
// Log.verbose("DrawLine : " + this.position + " to " + _dest);
if (this.position.x() == _dest.x() && this.position.y() == _dest.y() && this.position.z() == _dest.z()) {
// Log.warning("Try to draw a line width 0");
return;
}
// teta = tan-1(oposer/adjacent)
float teta = 0;
if (this.position.x() <= _dest.x()) {
teta = FMath.atan((_dest.y() - this.position.y()) / (_dest.x() - this.position.x()));
} else {
teta = FMath.PI + FMath.atan((_dest.y() - this.position.y())) / (_dest.x() - this.position.x());
}
if (teta < 0) {
teta += 2 * FMath.PI;
} else if (teta > 2 * FMath.PI) {
teta -= 2 * FMath.PI;
}
// Log.debug("teta = " + (teta*180/(FMath.PI)) + " deg." );
float offsety = FMath.sin(teta - FMath.PI / 2) * (this.thickness / 2);
float offsetx = FMath.cos(teta - FMath.PI / 2) * (this.thickness / 2);
setPoint(new Vector3f(this.position.x() - offsetx, this.position.y() - offsety, this.position.z()));
setPoint(new Vector3f(this.position.x() + offsetx, this.position.y() + offsety, this.position.z()));
setPoint(new Vector3f(_dest.x() + offsetx, _dest.y() + offsety, this.position.z()));
setPoint(new Vector3f(_dest.x() + offsetx, _dest.y() + offsety, _dest.z()));
setPoint(new Vector3f(_dest.x() - offsetx, _dest.y() - offsety, _dest.z()));
setPoint(new Vector3f(this.position.x() - offsetx, this.position.y() - offsety, _dest.z()));
// update the system position :
this.position = _dest;
};
/**
* @brief load the openGL program and get all the ID needed
*/
private void loadProgram() {
// remove previous loading ... in case
unLoadProgram();
// oad the new ...
this.GLprogram = ResourceProgram.create(new Uri("DATA", "color3.vert", "ewol"),
new Uri("DATA", "color3.frag", "ewol"));
// get the shader resource :
if (this.GLprogram != null) {
this.GLPosition = this.GLprogram.getAttribute("EW_coord3d");
this.GLColor = this.GLprogram.getAttribute("EW_color");
this.GLMatrix = this.GLprogram.getUniform("EW_MatrixTransformation");
this.GLMatrixPosition = this.GLprogram.getUniform("EW_MatrixPosition");
}
};
public void rectangle(final Vector2f _dest) {
rectangle(new Vector3f(_dest.x(), _dest.y(), 0));
};
/**
* @brief draw a 2D rectangle to the position requested.
* @param[in] _dest Position the the end of the rectangle
*/
public void rectangle(final Vector3f _dest) {
resetCount();
internalSetColor(this.color);
/*
* Bitmap position xA xB yC *------* | | | | yD *------*
*/
float dxA = this.position.x();
float dxB = _dest.x();
if (dxA > dxB) {
// inverse order :
float tmp = dxA;
dxA = dxB;
dxB = tmp;
}
float dyC = this.position.y();
float dyD = _dest.y();
if (dyC > dyD) {
// inverse order :
float tmp = dyC;
dyC = dyD;
dyD = tmp;
}
if (true == this.clippingEnable) {
if (dxA < this.clippingPosStart.x()) {
dxA = this.clippingPosStart.x();
}
if (dxB > this.clippingPosStop.x()) {
dxB = this.clippingPosStop.x();
}
if (dyC < this.clippingPosStart.y()) {
dyC = this.clippingPosStart.y();
}
if (dyD > this.clippingPosStop.y()) {
dyD = this.clippingPosStop.y();
}
}
if (dyC >= dyD || dxA >= dxB) {
return;
}
setPoint(new Vector3f(dxA, dyD, 0));
setPoint(new Vector3f(dxA, dyC, 0));
setPoint(new Vector3f(dxB, dyC, 0));
setPoint(new Vector3f(dxB, dyC, 0));
setPoint(new Vector3f(dxB, dyD, 0));
setPoint(new Vector3f(dxA, dyD, 0));
};
public void rectangleWidth(final Vector2f _size) {
rectangleWidth(new Vector3f(_size.x(), _size.y(), 0));
};
/**
* @brief draw a 2D rectangle to the requested size.
* @param[in] _size size of the rectangle
*/
public void rectangleWidth(final Vector3f _size) {
rectangle(this.position.add(_size));
}
/**
* @brief in case of some error the count can be reset
*/
private void resetCount() {
this.triElement = 0;
};
public void setClipping(final Vector2f _pos, final Vector2f _posEnd) {
setClipping(new Vector3f(_pos.x(), _pos.y(), -1), new Vector3f(_posEnd.x(), _posEnd.y(), 1));
};
/**
* @brief Request a clipping area for the text (next draw only)
* @param[in] _pos Start position of the clipping
* @param[in] _posEnd End position of the clipping
*/
public void setClipping(final Vector3f _pos, final Vector3f _posEnd) {
// note the internal system all time request to have a bounding all time in the
// same order
this.clippingPosStop = Vector3f.max(_pos, _posEnd);
this.clippingPosStart = Vector3f.min(_pos, _posEnd);
this.clippingEnable = true;
}
/**
* @brief enable/Disable the clipping (without lose the current clipping
* position)
* @brief _newMode The new status of the clipping
*/
public void setClippingMode(final boolean _newMode) {
this.clippingEnable = _newMode;
}
public void setClippingWidth(final Vector2f _pos, final Vector2f _width) {
setClippingWidth(new Vector3f(_pos.x(), _pos.y(), -1), new Vector3f(_width.x(), _width.y(), 2));
}
/**
* @brief Request a clipping area for the text (next draw only)
* @param[in]_ pos Start position of the clipping
* @param[in] _width Width size of the clipping
*/
public void setClippingWidth(final Vector3f _pos, final Vector3f _width) {
setClipping(_pos, _pos.add(_width));
};
/**
* @brief set the Color of the current foreground font
* @param[in] _color Color to set on foreground (for next print)
*/
public void setColor(final Color _color) {
this.color = _color;
};
/**
* @brief set the background color of the font (for selected Text (not the
* global BG))
* @param[in] _color Color to set on background (for next print)
*/
public void setColorBg(final Color _color) {
this.colorBg = _color;
};
/**
* @brief internal add of the specific point
* @param[in] _point The requeste dpoint to add
*/
private void setPoint(final Vector3f point) {
this.triangle[this.triElement] = point;
this.triElement++;
if (this.triElement >= 3) {
generateTriangle();
}
this.VBO.flush();
}
public void setPos(final Vector2f _pos) {
setPos(new Vector3f(_pos.x(), _pos.y(), 0));
};
/**
* @brief set position for the next text writen
* @param[in] _pos Position of the text (in 3D)
*/
public void setPos(final Vector3f _pos) {
this.position = _pos;
};
public void setRelPos(final Vector2f _pos) {
setRelPos(new Vector3f(_pos.x(), _pos.y(), 0));
}
/**
* @brief set relative position for the next text writen
* @param[in] _pos ofset apply of the text (in 3D)
*/
public void setRelPos(final Vector3f _pos) {
this.position = this.position.add(_pos);
}
/**
* @brief Specify the line thickness for the next elements
* @param[in] _thickness The thickness disired for the next print
*/
public void setThickness(final float _thickness) {
this.thickness = _thickness;
// thickness must be positive
if (this.thickness < 0) {
this.thickness *= -1;
}
}
/**
* @brief Un-Load the openGL program and get all the ID needed
*/
private void unLoadProgram() {
this.GLprogram = null;
}
}

View File

@ -1,372 +0,0 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#include <ewol/debug.hpp>
#include <ewol/compositing/Text.hpp>
#include <ewol/context/Context.hpp>
#include <etk/types.hpp>
#include <etk/typeInfo.hpp>
ETK_DECLARE_TYPE(ewol::compositing::Text);
ewol::compositing::Text::Text( String _fontName, int _fontSize) :
this.font(null) {
setFont(_fontName, _fontSize);
}
ewol::compositing::Text::~Text() {
}
void ewol::compositing::Text::drawMT( Matrix4f _transformationMatrix, boolean _enableDepthTest) {
// draw BG in any case:
this.vectorialDraw.draw();
if ( this.VBO.bufferSize(this.vboIdCoord) <= 0
|| this.font == null) {
// TODO : set it back ...
//Log.warning("Nothink to draw...");
return;
}
if (this.font == null) {
Log.warning("no font...");
return;
}
if (this.GLprogram == null) {
Log.error("No shader ...");
return;
}
if (_enableDepthTest == true) {
gale::openGL::enable(gale::openGL::flag_depthTest);
}
// set Matrix : translation/positionMatrix
Matrix4f projMatrix = gale::openGL::getMatrix();
Matrix4f camMatrix = gale::openGL::getCameraMatrix();
Matrix4f tmpMatrix = projMatrix * camMatrix * _transformationMatrix;
this.GLprogram.use();
this.GLprogram.uniformMatrix(this.GLMatrix, tmpMatrix);
// Texture:
this.GLprogram.setTexture0(this.GLtexID, this.font.getRendererId());
this.GLprogram.uniform1i(this.GLtextWidth, this.font.getOpenGlSize().x());
this.GLprogram.uniform1i(this.GLtextHeight, this.font.getOpenGlSize().x());
// position:
this.GLprogram.sendAttributePointer(this.GLPosition, this.VBO, this.vboIdCoord);
// Texture:
this.GLprogram.sendAttributePointer(this.GLtexture, this.VBO, this.vboIdCoordText);
// color:
this.GLprogram.sendAttributePointer(this.GLColor, this.VBO, this.vboIdColor);
// Request the draw od the elements:
gale::openGL::drawArrays(gale::openGL::renderMode::triangle, 0, this.VBO.bufferSize(this.vboIdCoord));
this.GLprogram.unUse();
if (_enableDepthTest == true) {
gale::openGL::disable(gale::openGL::flag_depthTest);
}
}
void ewol::compositing::Text::drawD(boolean _disableDepthTest) {
// draw BG in any case:
this.vectorialDraw.draw(_disableDepthTest);
if ( this.VBO.bufferSize(this.vboIdCoord) <= 0
|| this.font == null) {
//Log.warning("Nothink to draw...");
return;
}
if (this.font == null) {
Log.warning("no font...");
return;
}
if (this.GLprogram == null) {
Log.error("No shader ...");
return;
}
// set Matrix : translation/positionMatrix
Matrix4f tmpMatrix = gale::openGL::getMatrix()*this.matrixApply;
this.GLprogram.use();
this.GLprogram.uniformMatrix(this.GLMatrix, tmpMatrix);
// Texture :
this.GLprogram.setTexture0(this.GLtexID, this.font.getRendererId());
this.GLprogram.uniform1i(this.GLtextWidth, this.font.getOpenGlSize().x());
this.GLprogram.uniform1i(this.GLtextHeight, this.font.getOpenGlSize().x());
// position:
this.GLprogram.sendAttributePointer(this.GLPosition, this.VBO, this.vboIdCoord);
// Texture:
this.GLprogram.sendAttributePointer(this.GLtexture, this.VBO, this.vboIdCoordText);
// color:
this.GLprogram.sendAttributePointer(this.GLColor, this.VBO, this.vboIdColor);
// Request the draw od the elements :
gale::openGL::drawArrays(gale::openGL::renderMode::triangle, 0, this.VBO.bufferSize(this.vboIdCoord));
this.GLprogram.unUse();
}
float ewol::compositing::Text::getSize() {
if (this.font == null) {
Log.warning("no font...");
return 1.0f;
}
return this.font.getFontSize();
}
float ewol::compositing::Text::getHeight() {
if (this.font == null) {
Log.warning("no font...");
return 10.0f;
}
return this.font.getHeight(this.mode);
}
ewol::GlyphProperty * ewol::compositing::Text::getGlyphPointer(Character _charcode) {
if (this.font == null) {
Log.warning("no font...");
return null;
}
return this.font.getGlyphPointer(_charcode, this.mode);
}
void ewol::compositing::Text::setFontSize(int _fontSize) {
// get old size
String fontName = "";
if (this.font != null) {
fontName = this.font.getName();
// Remove the :XX for the size ...
int pos = fontName.rfind(':');
fontName.erase(pos, fontName.size()-pos);
}
setFont(fontName, _fontSize);
}
void ewol::compositing::Text::setFontName( String _fontName) {
// get old size
int fontSize = -1;
if (this.font != null) {
fontSize = this.font.getFontSize();
}
setFont(_fontName, fontSize);
}
void ewol::compositing::Text::setFont(String _fontName, int _fontSize) {
clear();
// remove old one
ememory::Ptr<ewol::resource::TexturedFont> previousFont = this.font;
if (_fontSize <= 0) {
_fontSize = ewol::getContext().getFontDefault().getSize();
}
if (_fontName == "") {
_fontName = ewol::getContext().getFontDefault().getName();
}
_fontName += ":";
_fontName += etk::toString(_fontSize);
Log.verbose("plop : " + _fontName + " size=" + _fontSize + " result :" + _fontName);
// link to new one
this.font = ewol::resource::TexturedFont::create(_fontName);
if (this.font == null) {
Log.error("Can not get font resource");
this.font = previousFont;
}
}
void ewol::compositing::Text::setFontMode(enum ewol::font::mode _mode) {
if (this.font != null) {
this.mode = this.font.getWrappingMode(_mode);
}
}
void ewol::compositing::Text::printChar( Character _charcode) {
// get a pointer on the glyph property :
ewol::GlyphProperty* myGlyph = getGlyphPointer(_charcode);
if (null == myGlyph) {
Log.error(" font does not really existed ...");
return;
}
int fontSize = getSize();
int fontHeigh = getHeight();
// get the kerning ofset :
float kerningOffset = 0;
if (this.kerning == true) {
kerningOffset = myGlyph.kerningGet(this.previousCharcode);
if (kerningOffset != 0) {
//Log.debug("Kerning between : '" + this.previousCharcode + "''" + myGlyph.this.UVal + "' value : " + kerningOffset);
}
}
// 0x01 == 0x20 == ' ';
if (_charcode != 0x01) {
/* Bitmap position
* xA xB
* yC *------*
* | |
* | |
* yD *------*
*/
float dxA = this.position.x() + myGlyph.this.bearing.x() + kerningOffset;
float dxB = dxA + myGlyph.this.sizeTexture.x();
float dyC = this.position.y() + myGlyph.this.bearing.y() + fontHeigh - fontSize;
float dyD = dyC - myGlyph.this.sizeTexture.y();
float tuA = myGlyph.this.texturePosStart.x();
float tuB = tuA + myGlyph.this.texturePosSize.x();
float tvC = myGlyph.this.texturePosStart.y();
float tvD = tvC + myGlyph.this.texturePosSize.y();
// Clipping and drawing area
if( this.clippingEnable == true
LOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOMLOM ( dxB < this.clippingPosStart.x()
|| dxA > this.clippingPosStop.x()
|| dyC < this.clippingPosStart.y()
|| dyD > this.clippingPosStop.y() ) ) {
// Nothing to diplay ...
} else {
if (this.clippingEnable == true) {
// generata positions...
float TexSizeX = tuB - tuA;
if (dxA < this.clippingPosStart.x()) {
// clip display
float drawSize = this.clippingPosStart.x() - dxA;
// update element start display
dxA = this.clippingPosStart.x();
float addElement = TexSizeX * drawSize / (float)myGlyph.this.sizeTexture.x();
// update texture start X Pos
tuA += addElement;
}
if (dxB > this.clippingPosStop.x()) {
// clip display
float drawSize = dxB - this.clippingPosStop.x();
// update element start display
dxB = this.clippingPosStop.x();
float addElement = TexSizeX * drawSize / (float)myGlyph.this.sizeTexture.x();
// update texture start X Pos
tuB -= addElement;
}
float TexSizeY = tvC - tvD;
if (dyC > this.clippingPosStop.y()) {
// clip display
float drawSize = dyC - this.clippingPosStop.y();
// update element start display
dyC = this.clippingPosStop.y();
float addElement = TexSizeY * drawSize / (float)myGlyph.this.sizeTexture.y();
// update texture start X Pos
tvC -= addElement;
}
if (dyD < this.clippingPosStart.y()) {
// clip display
float drawSize = this.clippingPosStart.y() - dyD;
// update element start display
dyD = this.clippingPosStart.y();
float addElement = TexSizeY * drawSize / (float)myGlyph.this.sizeTexture.y();
// update texture start X Pos
tvD += addElement;
}
}
if( dxB <= dxA
|| dyD >= dyC) {
// nothing to do ...
} else {
/* Bitmap position
* 0------1
* | |
* | |
* 3------2
*/
if (this.needDisplay == true) {
Vector3f bitmapDrawPos[4];
bitmapDrawPos[0].setValue((int)dxA, (int)dyC, 0);
bitmapDrawPos[1].setValue((int)dxB, (int)dyC, 0);
bitmapDrawPos[2].setValue((int)dxB, (int)dyD, 0);
bitmapDrawPos[3].setValue((int)dxA, (int)dyD, 0);
/* texture Position :
* 0------1
* | |
* | |
* 3------2
*/
Vector2f texturePos[4];
texturePos[0].setValue(tuA+this.mode, tvC);
texturePos[1].setValue(tuB+this.mode, tvC);
texturePos[2].setValue(tuB+this.mode, tvD);
texturePos[3].setValue(tuA+this.mode, tvD);
// NOTE : Android does not support the Quads elements ...
/* Step 1 :
* ********
* ******
* ****
* **
*
*/
// set texture coordonates :
this.VBO.pushOnBuffer(this.vboIdCoordText, texturePos[0]);
this.VBO.pushOnBuffer(this.vboIdCoordText, texturePos[1]);
this.VBO.pushOnBuffer(this.vboIdCoordText, texturePos[2]);
// set display positions :
this.VBO.pushOnBuffer(this.vboIdCoord, bitmapDrawPos[0]);
this.VBO.pushOnBuffer(this.vboIdCoord, bitmapDrawPos[1]);
this.VBO.pushOnBuffer(this.vboIdCoord, bitmapDrawPos[2]);
// set the color
this.VBO.pushOnBuffer(this.vboIdColor, this.color);
this.VBO.pushOnBuffer(this.vboIdColor, this.color);
this.VBO.pushOnBuffer(this.vboIdColor, this.color);
/* Step 2 :
*
* **
* ****
* ******
* ********
*/
// set texture coordonates :
this.VBO.pushOnBuffer(this.vboIdCoordText, texturePos[0]);
this.VBO.pushOnBuffer(this.vboIdCoordText, texturePos[2]);
this.VBO.pushOnBuffer(this.vboIdCoordText, texturePos[3]);
// set display positions :
this.VBO.pushOnBuffer(this.vboIdCoord, bitmapDrawPos[0]);
this.VBO.pushOnBuffer(this.vboIdCoord, bitmapDrawPos[2]);
this.VBO.pushOnBuffer(this.vboIdCoord, bitmapDrawPos[3]);
// set the color
this.VBO.pushOnBuffer(this.vboIdColor, this.color);
this.VBO.pushOnBuffer(this.vboIdColor, this.color);
this.VBO.pushOnBuffer(this.vboIdColor, this.color);
}
}
}
}
// move the position :
//Log.debug(" 5 pos=" + this.position + " advance=" + myGlyph.this.advance.x() + " kerningOffset=" + kerningOffset);
this.position.setX(this.position.x() + myGlyph.this.advance.x() + kerningOffset);
//Log.debug(" 6 print '" + charcode + "' : start=" + this.sizeDisplayStart + " stop=" + this.sizeDisplayStop + " pos=" + this.position);
// Register the previous character
this.previousCharcode = _charcode;
this.VBO.flush();
return;
}
Vector3f ewol::compositing::Text::calculateSizeChar( Character _charcode) {
// get a pointer on the glyph property :
ewol::GlyphProperty * myGlyph = getGlyphPointer(_charcode);
int fontHeigh = getHeight();
if (myGlyph == null) {
if (this.font == null) {
Log.warning("no Glyph... in no font");
} else {
Log.warning("no Glyph... in font : " + this.font.getName());
}
return Vector3f((float)(0.2),
(float)(fontHeigh),
(float)(0.0));
}
// get the kerning ofset :
float kerningOffset = 0.0;
if (this.kerning == true) {
kerningOffset = myGlyph.kerningGet(this.previousCharcode);
}
Vector3f outputSize((float)(myGlyph.this.advance.x() + kerningOffset),
(float)(fontHeigh),
(float)(0.0));
// Register the previous character
this.previousCharcode = _charcode;
return outputSize;
}

View File

@ -1,56 +1,414 @@
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#pragma once
package org.atriasoft.ewol.compositing;
#include <etk/Color.hpp>
import java.util.ArrayList;
import java.util.List;
#include <ewol/debug.hpp>
#include <ewol/compositing/Compositing.hpp>
#include <ewol/compositing/Drawing.hpp>
#include <ewol/resource/TexturedFont.hpp>
#include <ewol/compositing/TextBase.hpp>
#include <exml/exml.hpp>
#include <etk/String.hpp>
import org.atriasoft.etk.Color;
import org.atriasoft.etk.math.Matrix4f;
import org.atriasoft.etk.math.Vector2f;
import org.atriasoft.etk.math.Vector3f;
import org.atriasoft.ewol.Ewol;
import org.atriasoft.ewol.internal.Log;
import org.atriasoft.ewol.resource.ResourceTexturedFont;
import org.atriasoft.ewol.resource.font.FontMode;
import org.atriasoft.ewol.resource.font.GlyphProperty;
import org.atriasoft.gale.backend3d.OpenGL;
#include <etk/Color.hpp>
class Text extends TextBase {
protected ResourceTexturedFont font; // !< Font resources
namespace ewol {
namespace compositing {
class Text : public ewol::compositing::TextBase {
protected:
ememory::Ptr<ewol::resource::TexturedFont> this.font; //!< Font resources
public:
/**
* @brief generic ructor
* @param[in] _fontName Name of the font that might be loaded
* @param[in] _fontSize size of the font that might be loaded
*/
Text( String _fontName="", int _fontSize=-1);
/**
* @brief generic destructor
*/
~Text();
public:
void drawD(boolean _disableDepthTest);
void drawMT( Matrix4f _transformationMatrix, boolean _enableDepthTest);
protected:
float this.size;
public:
float getHeight();
float getSize();
ewol::GlyphProperty * getGlyphPointer(Character _charcode);
public:
void setFontSize(int _fontSize);
void setFontName( String _fontName);
void setFont(String _fontName, int _fontSize);
void setFontMode(enum ewol::font::mode _mode);
void printChar( Character _charcode);
Vector3f calculateSizeChar( Character _charcode);
};
List<Vector3f> pointPositions = new ArrayList<>();
List<Vector2f> texturePositions = new ArrayList<>();
List<Color> colors = new ArrayList<>();
protected float size;
/**
* @brief generic ructor
* @param[in] _fontName Name of the font that might be loaded
* @param[in] _fontSize size of the font that might be loaded
*/
public Text() {
this("");
}
}
public Text(final String _fontName) {
this(_fontName, -1);
}
public Text(final String _fontName, final int _fontSize) {
setFont(_fontName, _fontSize);
}
@Override
public Vector3f calculateSizeChar(final Character _charcode) {
// get a pointer on the glyph property :
GlyphProperty myGlyph = getGlyphPointer(_charcode);
int fontHeigh = (int) getHeight();
if (myGlyph == null) {
if (this.font == null) {
Log.warning("no Glyph... in no font");
} else {
Log.warning("no Glyph... in font : " + this.font.getName());
}
return new Vector3f((float) (0.2), (fontHeigh), (float) (0.0));
}
// get the kerning ofset :
float kerningOffset = 0.0f;
if (this.kerning == true) {
kerningOffset = myGlyph.kerningGet(this.previousCharcode);
}
Vector3f outputSize = new Vector3f(myGlyph.advance.x() + kerningOffset, (fontHeigh), 0.0f);
// Register the previous character
this.previousCharcode = _charcode;
return outputSize;
}
@Override
public void clear() {
// call upper class
super.clear();
this.texturePositions.clear();
// set display positions :
this.pointPositions.clear();
// set the color
this.colors.clear();
}
@Override
public void drawD(final boolean _disableDepthTest) {
// draw BG in any case:
// TODO this.vectorialDraw.draw(_disableDepthTest);
// TODO : do it only one time (when needed ...)
// set texture coordonates :
this.VBO.setVboData(vboIdCoordText, this.texturePositions.toArray(Vector3f[]::new));
// set display positions :
this.VBO.setVboData(vboIdCoord, this.pointPositions.toArray(Vector2f[]::new));
// set the color
this.VBO.setVboData(vboIdColor, this.colors.toArray(Color[]::new));
// TODO : do it only one time (when needed ...) --------- end -------
if (this.VBO.bufferSize(TextBase.vboIdCoord) <= 0 || this.font == null) {
// Log.warning("Nothink to draw...");
return;
}
if (this.font == null) {
Log.warning("no font...");
return;
}
if (this.GLprogram == null) {
Log.error("No shader ...");
return;
}
// set Matrix : translation/positionMatrix
Matrix4f tmpMatrix = OpenGL.getMatrix().multiply(this.matrixApply);
this.GLprogram.use();
this.GLprogram.uniformMatrix(this.GLMatrix, tmpMatrix);
// Texture :
this.GLprogram.setTexture0(this.GLtexID, this.font.getRendererId());
this.GLprogram.uniformInt(this.GLtextWidth, this.font.getOpenGlSize().x());
this.GLprogram.uniformInt(this.GLtextHeight, this.font.getOpenGlSize().x());
// position:
this.GLprogram.sendAttributePointer(this.GLPosition, this.VBO, TextBase.vboIdCoord);
// Texture:
this.GLprogram.sendAttributePointer(this.GLtexture, this.VBO, TextBase.vboIdCoordText);
// color:
this.GLprogram.sendAttributePointer(this.GLColor, this.VBO, TextBase.vboIdColor);
// Request the draw od the elements :
OpenGL.drawArrays(OpenGL.RenderMode.triangle, 0, this.VBO.bufferSize(TextBase.vboIdCoord));
this.GLprogram.unUse();
}
@Override
public void drawMT(final Matrix4f _transformationMatrix, final boolean _enableDepthTest) {
// draw BG in any case:
// TODO this.vectorialDraw.draw();
// TODO : do it only one time (when needed ...)
// set texture coordonates :
this.VBO.setVboData(vboIdCoordText, this.texturePositions.toArray(Vector3f[]::new));
// set display positions :
this.VBO.setVboData(vboIdCoord, this.pointPositions.toArray(Vector2f[]::new));
// set the color
this.VBO.setVboData(vboIdColor, this.colors.toArray(Color[]::new));
// TODO : do it only one time (when needed ...) --------- end -------
if (this.VBO.bufferSize(TextBase.vboIdCoord) <= 0 || this.font == null) {
// TODO : set it back ...
// Log.warning("Nothink to draw...");
return;
}
if (this.font == null) {
Log.warning("no font...");
return;
}
if (this.GLprogram == null) {
Log.error("No shader ...");
return;
}
if (_enableDepthTest == true) {
OpenGL.enable(OpenGL.Flag.flag_depthTest);
}
// set Matrix : translation/positionMatrix
Matrix4f projMatrix = OpenGL.getMatrix();
Matrix4f camMatrix = OpenGL.getCameraMatrix();
Matrix4f tmpMatrix = projMatrix.multiply(camMatrix).multiply(_transformationMatrix);
this.GLprogram.use();
this.GLprogram.uniformMatrix(this.GLMatrix, tmpMatrix);
// Texture:
this.GLprogram.setTexture0(this.GLtexID, this.font.getRendererId());
this.GLprogram.uniformInt(this.GLtextWidth, this.font.getOpenGlSize().x());
this.GLprogram.uniformInt(this.GLtextHeight, this.font.getOpenGlSize().x());
// position:
this.GLprogram.sendAttributePointer(this.GLPosition, this.VBO, TextBase.vboIdCoord);
// Texture:
this.GLprogram.sendAttributePointer(this.GLtexture, this.VBO, TextBase.vboIdCoordText);
// color:
this.GLprogram.sendAttributePointer(this.GLColor, this.VBO, TextBase.vboIdColor);
// Request the draw od the elements:
OpenGL.drawArrays(OpenGL.RenderMode.triangle, 0, this.VBO.bufferSize(TextBase.vboIdCoord));
this.GLprogram.unUse();
if (_enableDepthTest == true) {
OpenGL.disable(OpenGL.Flag.flag_depthTest);
}
}
@Override
public GlyphProperty getGlyphPointer(final Character _charcode) {
if (this.font == null) {
Log.warning("no font...");
return null;
}
return this.font.getGlyph(_charcode, this.mode);
}
@Override
public float getHeight() {
if (this.font == null) {
Log.warning("no font...");
return 10.0f;
}
return this.font.getHeight(this.mode);
}
@Override
public float getSize() {
if (this.font == null) {
Log.warning("no font...");
return 1.0f;
}
return this.font.getFontSize();
}
@Override
public void printChar(final Character _charcode) {
// get a pointer on the glyph property :
GlyphProperty myGlyph = getGlyphPointer(_charcode);
if (myGlyph == null) {
Log.error(" font does not really existed ...");
return;
}
int fontSize = (int) getSize();
int fontHeigh = (int) getHeight();
// get the kerning ofset :
float kerningOffset = 0;
if (this.kerning == true) {
kerningOffset = myGlyph.kerningGet(this.previousCharcode);
if (kerningOffset != 0) {
// Log.debug("Kerning between : '" + this.previousCharcode + "''" + myGlyph.UVal
// + "' value : " + kerningOffset);
}
}
// 0x01 == 0x20 == ' ';
if (_charcode != 0x01) {
/*
* Bitmap position xA xB yC *------* | | | | yD *------*
*/
float dxA = this.position.x() + myGlyph.bearing.x() + kerningOffset;
float dxB = dxA + myGlyph.sizeTexture.x();
float dyC = this.position.y() + myGlyph.bearing.y() + fontHeigh - fontSize;
float dyD = dyC - myGlyph.sizeTexture.y();
float tuA = myGlyph.texturePosStart.x();
float tuB = tuA + myGlyph.texturePosSize.x();
float tvC = myGlyph.texturePosStart.y();
float tvD = tvC + myGlyph.texturePosSize.y();
// Clipping and drawing area
if (this.clippingEnable == true && (dxB < this.clippingPosStart.x() || dxA > this.clippingPosStop.x()
|| dyC < this.clippingPosStart.y() || dyD > this.clippingPosStop.y())) {
// Nothing to diplay ...
} else {
if (this.clippingEnable == true) {
// generata positions...
float TexSizeX = tuB - tuA;
if (dxA < this.clippingPosStart.x()) {
// clip display
float drawSize = this.clippingPosStart.x() - dxA;
// update element start display
dxA = this.clippingPosStart.x();
float addElement = TexSizeX * drawSize / myGlyph.sizeTexture.x();
// update texture start X Pos
tuA += addElement;
}
if (dxB > this.clippingPosStop.x()) {
// clip display
float drawSize = dxB - this.clippingPosStop.x();
// update element start display
dxB = this.clippingPosStop.x();
float addElement = TexSizeX * drawSize / myGlyph.sizeTexture.x();
// update texture start X Pos
tuB -= addElement;
}
float TexSizeY = tvC - tvD;
if (dyC > this.clippingPosStop.y()) {
// clip display
float drawSize = dyC - this.clippingPosStop.y();
// update element start display
dyC = this.clippingPosStop.y();
float addElement = TexSizeY * drawSize / myGlyph.sizeTexture.y();
// update texture start X Pos
tvC -= addElement;
}
if (dyD < this.clippingPosStart.y()) {
// clip display
float drawSize = this.clippingPosStart.y() - dyD;
// update element start display
dyD = this.clippingPosStart.y();
float addElement = TexSizeY * drawSize / myGlyph.sizeTexture.y();
// update texture start X Pos
tvD += addElement;
}
}
if (dxB <= dxA || dyD >= dyC) {
// nothing to do ...
} else {
/*
* Bitmap position 0------1 | | | | 3------2
*/
if (this.needDisplay == true) {
Vector3f drawPosition0 = new Vector3f((int) dxA, (int) dyC, 0);
Vector3f drawPosition1 = new Vector3f((int) dxB, (int) dyC, 0);
Vector3f drawPosition2 = new Vector3f((int) dxB, (int) dyD, 0);
Vector3f drawPosition3 = new Vector3f((int) dxA, (int) dyD, 0);
/*
* texture Position : 0------1 | | | | 3------2
*/
Vector2f texturePos0 = new Vector2f(tuA + this.mode.getValue(), tvC);
Vector2f texturePos1 = new Vector2f(tuB + this.mode.getValue(), tvC);
Vector2f texturePos2 = new Vector2f(tuB + this.mode.getValue(), tvD);
Vector2f texturePos3 = new Vector2f(tuA + this.mode.getValue(), tvD);
// NOTE : Android does not support the Quads elements ...
/*
* Step 1 : ******** ****** **** **
*
*/
// set texture coordonates :
this.texturePositions.add(texturePos0);
this.texturePositions.add(texturePos1);
this.texturePositions.add(texturePos2);
// set display positions :
this.pointPositions.add(drawPosition0);
this.pointPositions.add(drawPosition1);
this.pointPositions.add(drawPosition2);
// set the color
this.colors.add(this.color);
this.colors.add(this.color);
this.colors.add(this.color);
/*
* Step 2 :
*
* ** **** ****** ********
*/
// set texture coordonates :
this.texturePositions.add(texturePos0);
this.texturePositions.add(texturePos2);
this.texturePositions.add(texturePos3);
// set display positions :
this.pointPositions.add(drawPosition0);
this.pointPositions.add(drawPosition2);
this.pointPositions.add(drawPosition3);
// set the color
this.colors.add(this.color);
this.colors.add(this.color);
this.colors.add(this.color);
}
}
}
}
// move the position :
// Log.debug(" 5 pos=" + this.position + " advance=" + myGlyph.advance.x() + "
// kerningOffset=" + kerningOffset);
this.position = this.position.withX(this.position.x() + myGlyph.advance.x() + kerningOffset);
// Log.debug(" 6 print '" + charcode + "' : start=" + this.sizeDisplayStart + "
// stop=" + this.sizeDisplayStop + " pos=" + this.position);
// Register the previous character
this.previousCharcode = _charcode;
this.VBO.flush();
return;
}
@Override
public void setFont(String _fontName, int _fontSize) {
clear();
// remove old one
ResourceTexturedFont previousFont = this.font;
if (_fontSize <= 0) {
_fontSize = Ewol.getContext().getFontDefault().getSize();
}
if (_fontName == "") {
_fontName = Ewol.getContext().getFontDefault().getName();
}
_fontName += ":";
_fontName += _fontSize;
Log.verbose("plop : " + _fontName + " size=" + _fontSize + " result :" + _fontName);
// link to new one
this.font = ResourceTexturedFont.create(_fontName);
if (this.font == null) {
Log.error("Can not get font resource");
this.font = previousFont;
}
}
@Override
public void setFontMode(final FontMode _mode) {
if (this.font != null) {
this.mode = this.font.getWrappingMode(_mode);
}
}
@Override
public void setFontName(final String _fontName) {
// get old size
int fontSize = -1;
if (this.font != null) {
fontSize = this.font.getFontSize();
}
setFont(_fontName, fontSize);
}
@Override
public void setFontSize(final int _fontSize) {
// get old size
String fontName = "";
if (this.font != null) {
fontName = this.font.getName();
// Remove the :XX for the size ...
int pos = fontName.lastIndexOf(':');
fontName = fontName.substring(0, pos);
}
setFont(fontName, _fontSize);
}
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,29 @@
package org.atriasoft.ewol.compositing.tools;
import org.atriasoft.etk.Color;
import org.atriasoft.ewol.resource.font.FontMode;
public record TextDecoration(
final Color colorBG,
final Color colorFg,
final FontMode mode) {
@SuppressWarnings("preview")
public record TextDecoration(Color colorFG, Color colorBG, FontMode mode) {
public TextDecoration(final Color colorFG, final Color colorBG, final FontMode mode) {
this.colorFG = colorFG;
this.colorBG = colorBG;
this.mode = mode;
}
public TextDecoration() {
this(Color.BLACK, Color.NONE, FontMode.Regular);
}
public TextDecoration withFG(final Color color) {
return new TextDecoration(color, this.colorBG, this.mode);
}
public TextDecoration withBG(final Color color) {
return new TextDecoration(this.colorFG, color, this.mode);
}
public TextDecoration withMode(final FontMode mode) {
return new TextDecoration(this.colorFG, this.colorBG, mode);
}
}

View File

@ -366,7 +366,7 @@ public abstract class EwolContext extends Application {
return;
}
final Vector2f size = getSize();
this.windowsCurrent.setSize(new Vector2f((int) size.x, (int) size.y));
this.windowsCurrent.setSize(new Vector2f((int) size.x(), (int) size.y()));
this.windowsCurrent.onChangeSize();
}

View File

@ -78,13 +78,13 @@ class InputManager {
eventMouseSaved2[_idInput].destinationInputId = 0;
eventMouseSaved2[_idInput].lastTimeEvent = new Clock();
eventMouseSaved2[_idInput].curentWidgetEvent = null;
eventMouseSaved2[_idInput].origin.setValue(0, 0);
eventMouseSaved2[_idInput].size.setValue(99999999, 99999999);
eventMouseSaved2[_idInput].downStart.setValue(0, 0);
eventMouseSaved2[_idInput].origin = new Vector2f(0, 0);
eventMouseSaved2[_idInput].size = new Vector2f(99999999, 99999999);
eventMouseSaved2[_idInput].downStart = new Vector2f(0, 0);
eventMouseSaved2[_idInput].isDown = false;
eventMouseSaved2[_idInput].isInside = false;
eventMouseSaved2[_idInput].nbClickEvent = 0;
eventMouseSaved2[_idInput].posEvent.setValue(0, 0);
eventMouseSaved2[_idInput].posEvent = new Vector2f(0, 0);
}
/**
@ -187,8 +187,8 @@ class InputManager {
tmpWidget = tmpWindows.getWidgetAtPos(_pos);
}
if (tmpWidget != eventTable[_pointerID].curentWidgetEvent.get()
|| (eventTable[_pointerID].isInside == true && (eventTable[_pointerID].origin.x > _pos.x || eventTable[_pointerID].origin.y > _pos.y
|| (eventTable[_pointerID].origin.x + eventTable[_pointerID].size.x) < _pos.x || (eventTable[_pointerID].origin.y + eventTable[_pointerID].size.y) < _pos.y))) {
|| (eventTable[_pointerID].isInside == true && (eventTable[_pointerID].origin.x() > _pos.x() || eventTable[_pointerID].origin.y() > _pos.y()
|| (eventTable[_pointerID].origin.x() + eventTable[_pointerID].size.x()) < _pos.x() || (eventTable[_pointerID].origin.y() + eventTable[_pointerID].size.y()) < _pos.y()))) {
eventTable[_pointerID].isInside = false;
//Log.debug("GUI : Input ID=" + _pointerID + " == >" + eventTable[_pointerID].destinationInputId + " [LEAVE] " + _pos);
eventTable[_pointerID].posEvent = _pos;
@ -215,15 +215,15 @@ class InputManager {
localEventInput(_type, tmpWidget, eventTable[_pointerID].destinationInputId, KeyStatus.move, _pos);
} else if (eventTable[_pointerID].isUsed == true) {
if (eventTable[_pointerID].isInside == true) {
if (eventTable[_pointerID].origin.x > _pos.x || eventTable[_pointerID].origin.y > _pos.y || (eventTable[_pointerID].origin.x + eventTable[_pointerID].size.x) < _pos.x
|| (eventTable[_pointerID].origin.y + eventTable[_pointerID].size.y) < _pos.y) {
if (eventTable[_pointerID].origin.x() > _pos.x() || eventTable[_pointerID].origin.y() > _pos.y() || (eventTable[_pointerID].origin.x() + eventTable[_pointerID].size.x()) < _pos.x()
|| (eventTable[_pointerID].origin.y() + eventTable[_pointerID].size.y()) < _pos.y()) {
eventTable[_pointerID].isInside = false;
//Log.debug("GUI : Input ID=" + _pointerID + " == >" + eventTable[_pointerID].destinationInputId + " [LEAVE] " + _pos);
eventTable[_pointerID].posEvent = _pos;
localEventInput(_type, eventTable[_pointerID].curentWidgetEvent.get(), eventTable[_pointerID].destinationInputId, KeyStatus.leave, _pos);
}
} else if ((eventTable[_pointerID].origin.x <= _pos.x && (eventTable[_pointerID].origin.x + eventTable[_pointerID].size.x) >= _pos.x)
&& (eventTable[_pointerID].origin.y <= _pos.y && (eventTable[_pointerID].origin.y + eventTable[_pointerID].size.y) >= _pos.y)) {
} else if ((eventTable[_pointerID].origin.x() <= _pos.x() && (eventTable[_pointerID].origin.x() + eventTable[_pointerID].size.x()) >= _pos.x())
&& (eventTable[_pointerID].origin.y() <= _pos.y() && (eventTable[_pointerID].origin.y() + eventTable[_pointerID].size.y()) >= _pos.y())) {
eventTable[_pointerID].isInside = true;
//Log.debug("GUI : Input ID=" + _pointerID + " == >" + eventTable[_pointerID].destinationInputId + " [ENTER] " + _pos);
eventTable[_pointerID].posEvent = _pos;
@ -291,7 +291,7 @@ class InputManager {
// we have an event previously ... check delay between click and offset position
if (currentTime.less(eventTable[_pointerID].lastTimeEvent).isGreaterThan(localLimit.sepatateTime)) {
cleanElement(eventTable, _pointerID);
} else if (FMath.abs(eventTable[_pointerID].downStart.x - _pos.x) >= localLimit.DpiOffset || FMath.abs(eventTable[_pointerID].downStart.y - _pos.y) >= localLimit.DpiOffset) {
} else if (FMath.abs(eventTable[_pointerID].downStart.x() - _pos.x()) >= localLimit.DpiOffset || FMath.abs(eventTable[_pointerID].downStart.y() - _pos.y()) >= localLimit.DpiOffset) {
cleanElement(eventTable, _pointerID);
}
}
@ -367,7 +367,7 @@ class InputManager {
// send up event after the single event to prevent multiple widget getting elements
localEventInput(_type, tmpWidget, _pointerID, KeyStatus.up, _pos);
// generate event (single)
if (FMath.abs(eventTable[_pointerID].downStart.x - _pos.x) < localLimit.DpiOffset && FMath.abs(eventTable[_pointerID].downStart.y - _pos.y) < localLimit.DpiOffset) {
if (FMath.abs(eventTable[_pointerID].downStart.x() - _pos.x()) < localLimit.DpiOffset && FMath.abs(eventTable[_pointerID].downStart.y() - _pos.y()) < localLimit.DpiOffset) {
// Save current position :
eventTable[_pointerID].downStart = _pos;
// save start time

View File

@ -38,7 +38,7 @@ public class ObjectManager {
Log.todo("set this back ...");
//this.periodicCall.setPeriodic(true);
// set the basic time properties :
this.applWakeUpTime = Clock.now();
this.applWakeUpTime = Time.now();
this.lastPeriodicCallTime = new Clock(this.applWakeUpTime.get());
}

View File

@ -1,3 +1,5 @@
package org.atriasoft.ewol.object;
/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved

View File

@ -16,67 +16,90 @@ import org.atriasoft.ewol.internal.Log;
import org.atriasoft.ewol.resource.font.FontBase;
import org.atriasoft.ewol.resource.font.FontMode;
import org.atriasoft.ewol.resource.font.GlyphProperty;
import org.atriasoft.gale.resource.Resource;
public class ResourceTexturedFont extends ResourceTexture2 {
public static ResourceTexturedFont create(final String fontName) {
ResourceTexturedFont resource;
Resource resource2;
if (fontName.isEmpty() == false && fontName.contentEquals("---")) {
resource2 = getManager().localKeep(fontName);
} else {
Log.error("Can not create a shader without a filaname");
return null;
}
if (resource2 != null) {
if (resource2 instanceof ResourceTexturedFont) {
resource2.keep();
return (ResourceTexturedFont) resource2;
}
Log.critical("Request resource fontName : '" + fontName + "' With the wrong type (dynamic cast error)");
return null;
}
resource = new ResourceTexturedFont(fontName);
getManager().localAdd(resource);
return resource;
}
/**
* @brief Get all the Path contain in the specidy path:
* @param[in] _path Generic path to parse ...
* @return The list of path found
* @example[start]
* auto out = explodeMultiplePath("DATA:///font?lib=ewol");
* // out contain: {"DATA:///font", "DATA:///font?lib=ewol"}
* @example[stop]
* @example[start] auto out = explodeMultiplePath("DATA:///font?lib=ewol"); //
* out contain: {"DATA:///font",
* "DATA:///font?lib=ewol"} @example[stop]
*/
private static List<Uri> explodeMultiplePath(final Uri _uri) {
final List<Uri> out = new ArrayList<>();
out.add(_uri);
return out;
}
private final Uri[] fileName = new Uri[4];
private int size = 10;
private final int[] height = new int[4];
// specific element to have the the know if the specify element is known...
// == > otherwise I can just generate italic ...
// == > Bold is a little more complicated (maybe with the bordersize)
// == > otherwise I can just generate italic ...
// == > Bold is a little more complicated (maybe with the bordersize)
private final FontBase[] font = new FontBase[4];
private final FontMode[] modeWraping = new FontMode[4]; //!< This is a wrapping mode to prevent the fact that no font is define for a specific mode
private final FontMode[] modeWraping = new FontMode[4]; // !< This is a wrapping mode to prevent the fact that no
// font is define for a specific mode
public GlyphProperty emptyGlyph;
public List<GlyphProperty>[] listElement;// = new (List<GlyphProperty>)[4];
// for the texture generation :
public Vector2i[] lastGlyphPos = new Vector2i[4];
public int[] lastRawHeigh = new int[4];
protected ResourceTexturedFont(final String _fontName) {
super(_fontName);
Log.debug("Load font : '" + _fontName + "'");
this.font[0] = null;
this.font[1] = null;
this.font[2] = null;
this.font[3] = null;
this.modeWraping[0] = FontMode.Regular;
this.modeWraping[1] = FontMode.Regular;
this.modeWraping[2] = FontMode.Regular;
this.modeWraping[3] = FontMode.Regular;
this.lastGlyphPos[0].setValue(1, 1);
this.lastGlyphPos[1].setValue(1, 1);
this.lastGlyphPos[2].setValue(1, 1);
this.lastGlyphPos[3].setValue(1, 1);
this.lastGlyphPos[0] = Vector2i.ONE;
this.lastGlyphPos[1] = Vector2i.ONE;
this.lastGlyphPos[2] = Vector2i.ONE;
this.lastGlyphPos[3] = Vector2i.ONE;
this.lastRawHeigh[0] = 0;
this.lastRawHeigh[1] = 0;
this.lastRawHeigh[2] = 0;
this.lastRawHeigh[3] = 0;
int tmpSize = 0;
// extarct name and size :
final String[] tmpList = _fontName.split(":");
if (tmpList.length == 1) {
this.size = 1;
Log.critical("Can not parse the font name: '" + _fontName + "' ??? ':' ");
@ -85,23 +108,22 @@ public class ResourceTexturedFont extends ResourceTexture2 {
// zsdefsdf
tmpSize = Integer.valueOf(tmpList[1]);
}
final String localName = tmpList[0];
if (tmpSize > 400) {
Log.error("Font size too big ==> limit at 400 when exceed ==> error: " + tmpSize + "==>30");
tmpSize = 30;
}
this.size = tmpSize;
final List<Uri> folderList = new ArrayList<>();
;
if (Ewol.getContext().getFontDefault().getUseExternal() == true) {
/*
#if defined(__TARGET_OS__Android)
folderList.pushBack(etk::Path("/system/fonts"));#elif defined(__TARGET_OS__Linux)
folderList.pushBack(etk::Path("/usr/share/fonts"));
#endif
*/
* #if defined(__TARGET_OS__Android)
* folderList.pushBack(etk::Path("/system/fonts"));#elif
* defined(__TARGET_OS__Linux)
* folderList.pushBack(etk::Path("/usr/share/fonts")); #endif
*/
}
final Uri applicationBaseFont = Ewol.getContext().getFontDefault().getFolder();
for (final Uri it : explodeMultiplePath(applicationBaseFont)) {
@ -109,38 +131,51 @@ public class ResourceTexturedFont extends ResourceTexture2 {
}
for (int folderID = 0; folderID < folderList.size(); folderID++) {
final List<Uri> output = Uri.listRecursive(folderList.get(folderID));
final String[] split = localName.split(";");
Log.debug("try to find font named : " + split + " in: " + output);
//Log.critical("parse string : " + split);
// Log.critical("parse string : " + split);
boolean hasFindAFont = false;
for (int jjj = 0; jjj < split.length; jjj++) {
Log.debug(" try with : '" + split[jjj] + "'");
for (int iii = 0; iii < output.size(); iii++) {
final String nameFolder = output.get(iii).getPath();
//Log.debug(" file : " + output.get(iii));
if (nameFolder.endsWith(split[jjj] + "-" + "bold" + ".ttf") == true || nameFolder.endsWith(split[jjj] + "-" + "b" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "-" + "bd" + ".ttf") == true || nameFolder.endsWith(split[jjj] + "bold" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "bd" + ".ttf") == true || nameFolder.endsWith(split[jjj] + "b" + ".ttf") == true) {
// Log.debug(" file : " + output.get(iii));
if (nameFolder.endsWith(split[jjj] + "-" + "bold" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "-" + "b" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "-" + "bd" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "bold" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "bd" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "b" + ".ttf") == true) {
Log.debug(" find Font [Bold] : " + output.get(iii));
this.fileName[FontMode.Bold.getValue()] = output.get(iii);
hasFindAFont = true;
} else if (nameFolder.endsWith(split[jjj] + "-" + "oblique" + ".ttf") == true || nameFolder.endsWith(split[jjj] + "-" + "italic" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "-" + "Light" + ".ttf") == true || nameFolder.endsWith(split[jjj] + "-" + "i" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "oblique" + ".ttf") == true || nameFolder.endsWith(split[jjj] + "italic" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "light" + ".ttf") == true || nameFolder.endsWith(split[jjj] + "i" + ".ttf") == true) {
} else if (nameFolder.endsWith(split[jjj] + "-" + "oblique" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "-" + "italic" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "-" + "Light" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "-" + "i" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "oblique" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "italic" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "light" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "i" + ".ttf") == true) {
Log.debug(" find Font [Italic] : " + output.get(iii));
this.fileName[FontMode.Italic.getValue()] = output.get(iii);
hasFindAFont = true;
} else if (nameFolder.endsWith(split[jjj] + "-" + "bolditalic" + ".ttf") == true || nameFolder.endsWith(split[jjj] + "-" + "boldoblique" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "-" + "bi" + ".ttf") == true || nameFolder.endsWith(split[jjj] + "-" + "z" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "bolditalic" + ".ttf") == true || nameFolder.endsWith(split[jjj] + "boldoblique" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "bi" + ".ttf") == true || nameFolder.endsWith(split[jjj] + "z" + ".ttf") == true) {
} else if (nameFolder.endsWith(split[jjj] + "-" + "bolditalic" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "-" + "boldoblique" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "-" + "bi" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "-" + "z" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "bolditalic" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "boldoblique" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "bi" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "z" + ".ttf") == true) {
Log.debug(" find Font [Bold-Italic] : " + output.get(iii));
this.fileName[FontMode.BoldItalic.getValue()] = output.get(iii);
hasFindAFont = true;
} else if (nameFolder.endsWith(split[jjj] + "-" + "regular" + ".ttf") == true || nameFolder.endsWith(split[jjj] + "-" + "r" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "regular" + ".ttf") == true || nameFolder.endsWith(split[jjj] + "r" + ".ttf") == true
} else if (nameFolder.endsWith(split[jjj] + "-" + "regular" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "-" + "r" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "regular" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + "r" + ".ttf") == true
|| nameFolder.endsWith(split[jjj] + ".ttf") == true) {
Log.debug(" find Font [Regular] : " + output.get(iii));
this.fileName[FontMode.Regular.getValue()] = output.get(iii);
@ -177,17 +212,20 @@ public class ResourceTexturedFont extends ResourceTexture2 {
this.modeWraping[iii] = refMode;
}
}
for (int iiiFontId = 0; iiiFontId < 4; iiiFontId++) {
if (this.fileName[iiiFontId] == null) {
Log.debug("can not load FONT [" + iiiFontId + "] name : \"" + this.fileName[iiiFontId] + "\" == > size=" + this.size);
Log.debug("can not load FONT [" + iiiFontId + "] name : \"" + this.fileName[iiiFontId]
+ "\" == > size=" + this.size);
this.font[iiiFontId] = null;
continue;
}
Log.debug("Load FONT [" + iiiFontId + "] name : \"" + this.fileName[iiiFontId] + "\" == > size=" + this.size);
Log.debug("Load FONT [" + iiiFontId + "] name : \"" + this.fileName[iiiFontId] + "\" == > size="
+ this.size);
this.font[iiiFontId] = ResourceFontFreeType.create(this.fileName[iiiFontId]);
if (this.font[iiiFontId] == null) {
Log.debug("error in loading FONT [" + iiiFontId + "] name : \"" + this.fileName[iiiFontId] + "\" == > size=" + this.size);
Log.debug("error in loading FONT [" + iiiFontId + "] name : \"" + this.fileName[iiiFontId]
+ "\" == > size=" + this.size);
}
}
for (int iiiFontId = 0; iiiFontId < 4; iiiFontId++) {
@ -197,7 +235,8 @@ public class ResourceTexturedFont extends ResourceTexture2 {
continue;
}
this.height[iiiFontId] = this.font[iiiFontId].getHeight(this.size);
// TODO : basic font use 512 is better ... == > maybe estimate it with the dpi ???
// TODO : basic font use 512 is better ... == > maybe estimate it with the dpi
// ???
setImageSize(new Vector2i(256, 32));
// now we can acces directly on the image
this.data.clear();
@ -216,7 +255,7 @@ public class ResourceTexturedFont extends ResourceTexture2 {
Log.debug(" " + FontMode.Bold + " == >" + getWrappingMode(FontMode.Bold));
Log.debug(" " + FontMode.BoldItalic + " == >" + getWrappingMode(FontMode.BoldItalic));
}
/**
* @brief add a glyph in a texture font.
* @param[in] _val Char value to add.
@ -232,79 +271,85 @@ public class ResourceTexturedFont extends ResourceTexture2 {
// add the curent "char"
final GlyphProperty tmpchar = new GlyphProperty();
tmpchar.UVal = _val;
if (this.font[iii].getGlyphProperty(this.size, tmpchar) == true) {
//Log.debug("load char : '" + _val + "'=" + _val.get());
// Log.debug("load char : '" + _val + "'=" + _val.get());
hasChange = true;
// change line if needed ...
if (this.lastGlyphPos[iii].x + tmpchar.sizeTexture.x + 3 > this.data.getSize().x) {
this.lastGlyphPos[iii].setX(1);
this.lastGlyphPos[iii].add(new Vector2i(0, this.lastRawHeigh[iii]));
if (this.lastGlyphPos[iii].x() + tmpchar.sizeTexture.x() + 3 > this.data.getSize().x()) {
this.lastGlyphPos[iii] = new Vector2i(1, this.lastRawHeigh[iii]);
this.lastRawHeigh[iii] = 0;
}
while (this.lastGlyphPos[iii].y + tmpchar.sizeTexture.y + 3 > this.data.getSize().y) {
final Vector2i size = this.data.getSize();
size.setY(size.y * 2);
this.data.resize(size.x, size.y);
// note : need to rework all the lyer due to the fact that the texture is used by the faur type...
while (this.lastGlyphPos[iii].y() + tmpchar.sizeTexture.y() + 3 > this.data.getSize().y()) {
this.data.resize(this.data.getSize().x(), this.data.getSize().y() * 2);
// note : need to rework all the lyer due to the fact that the texture is used
// by the faur type...
for (int kkk = 0; kkk < 4; kkk++) {
// change the coordonate on the element in the texture
for (int jjj = 0; jjj < this.listElement[kkk].size(); ++jjj) {
this.listElement[kkk].get(jjj).texturePosStart.multiply(new Vector2f(1.0f, 0.5f));
this.listElement[kkk].get(jjj).texturePosSize.multiply(new Vector2f(1.0f, 0.5f));
this.listElement[kkk]
.get(jjj).texturePosStart = this.listElement[kkk].get(jjj).texturePosStart
.multiply(new Vector2f(1.0f, 0.5f));
this.listElement[kkk]
.get(jjj).texturePosSize = this.listElement[kkk].get(jjj).texturePosSize
.multiply(new Vector2f(1.0f, 0.5f));
}
}
}
// draw the glyph
this.font[iii].drawGlyph(this.data, this.size, this.lastGlyphPos[iii], tmpchar, iii);
// set video position
tmpchar.texturePosStart.setValue((float) this.lastGlyphPos[iii].x / (float) this.data.getSize().x, (float) this.lastGlyphPos[iii].y / (float) this.data.getSize().y);
tmpchar.texturePosSize.setValue((float) tmpchar.sizeTexture.x / this.data.getSize().x, (float) tmpchar.sizeTexture.y / this.data.getSize().y);
// update the maximum of the line hight :
if (this.lastRawHeigh[iii] < tmpchar.sizeTexture.y) {
tmpchar.texturePosStart = new Vector2f(
(float) this.lastGlyphPos[iii].x() / (float) this.data.getSize().x(),
(float) this.lastGlyphPos[iii].y() / (float) this.data.getSize().y());
tmpchar.texturePosSize = new Vector2f((float) tmpchar.sizeTexture.x() / this.data.getSize().x(),
(float) tmpchar.sizeTexture.y() / this.data.getSize().y());
// update the maximum of the line hight :
if (this.lastRawHeigh[iii] < tmpchar.sizeTexture.y()) {
// note : +1 is for the overlapping of the glyph (Part 2)
this.lastRawHeigh[iii] = tmpchar.sizeTexture.y + 1;
this.lastRawHeigh[iii] = tmpchar.sizeTexture.y() + 1;
}
// note : +1 is for the overlapping of the glyph (Part 3)
// update the Bitmap position drawing :
this.lastGlyphPos[iii].add(new Vector2i(tmpchar.sizeTexture.x + 1, 0));
// update the Bitmap position drawing :
this.lastGlyphPos[iii] = this.lastGlyphPos[iii].add(new Vector2i(tmpchar.sizeTexture.x() + 1, 0));
} else {
Log.warning("Did not find char : '" + _val + "'=" + _val);
tmpchar.setNotExist();
}
this.listElement[iii].add(tmpchar);
//this.font[iii].display;
// this.font[iii].display;
// generate the kerning for all the characters :
if (tmpchar.exist() == true) {
// TODO : set the kerning back ...
//this.font[iii].generateKerning(this.size, this.listElement[iii]);
// this.font[iii].generateKerning(this.size, this.listElement[iii]);
}
}
if (hasChange == true) {
flush();
Ewol.getContext().forceRedrawAll();
//egami::store(this.data, "fileFont.bmp"); // ==> for debug test only ...
// egami::store(this.data, "fileFont.bmp"); // ==> for debug test only ...
}
return hasChange;
}
/**
* @brief get the font height (user friendly)
* @return Dimention of the font the user requested
*/
private int getFontSize() {
public int getFontSize() {
return this.size;
}
/**
* @brief get the pointer on the coresponding glyph
* @param[in] _charcode The unicodeValue
* @param[in] _displayMode Mode to display the currrent font
* @return The pointer on the glyph == > never null
* @return The pointer on the glyph == > never null
*/
private synchronized GlyphProperty getGlyph(final Character _charcode, final FontMode _displayMode) {
//Log.debug("Get glyph property for mode: " + _displayMode + " == > wrapping index : " + this.modeWraping[_displayMode]);
public synchronized GlyphProperty getGlyph(final Character _charcode, final FontMode _displayMode) {
// Log.debug("Get glyph property for mode: " + _displayMode + " == > wrapping
// index : " + this.modeWraping[_displayMode]);
final int index = getIndex(_charcode, _displayMode);
if (index < 0 || index >= this.listElement[_displayMode.getValue()].size()) {
Log.error(" Try to get glyph index inexistant ... == > return the index 0 ... id=" + index);
@ -313,27 +358,28 @@ public class ResourceTexturedFont extends ResourceTexture2 {
}
return this.emptyGlyph;
}
//Log.error(" index=" + index);
//Log.error(" this.UVal=" + this.listElement[_displayMode][index].UVal);
//Log.error(" this.glyphIndex=" + this.listElement[_displayMode][index].glyphIndex);
//Log.error(" this.advance=" + this.listElement[_displayMode][index].advance);
//Log.error(" this.bearing=" + this.listElement[_displayMode][index].bearing);
// Log.error(" index=" + index);
// Log.error(" this.UVal=" + this.listElement[_displayMode][index].UVal);
// Log.error(" this.glyphIndex=" +
// this.listElement[_displayMode][index].glyphIndex);
// Log.error(" this.advance=" + this.listElement[_displayMode][index].advance);
// Log.error(" this.bearing=" + this.listElement[_displayMode][index].bearing);
return this.listElement[_displayMode.getValue()].get(index);
};
/**
* @brief get the display height of this font
* @param[in] _displayMode Mode to display the currrent font
* @return Dimention of the font need between 2 lines
*/
private int getHeight() {
public int getHeight() {
return this.height[FontMode.Regular.getValue()];
}
private int getHeight(final FontMode _displayMode) {
public int getHeight(final FontMode _displayMode) {
return this.height[_displayMode.getValue()];
}
/**
* @brief get the ID of a unicode charcode
* @param[in] _charcode The unicodeValue
@ -347,11 +393,12 @@ public class ResourceTexturedFont extends ResourceTexture2 {
return _charcode - 0x1F;
} else {
for (int iii = 0x80 - 0x20; iii < this.listElement[_displayMode.getValue()].size(); iii++) {
//Log.debug("search : '" + charcode + "' =?= '" + (this.listElement[displayMode])[iii].UVal + "'");
// Log.debug("search : '" + charcode + "' =?= '" +
// (this.listElement[displayMode])[iii].UVal + "'");
if (_charcode == this.listElement[_displayMode.getValue()].get(iii).UVal) {
//Log.debug("search : '" + charcode + "'");
// Log.debug("search : '" + charcode + "'");
if (this.listElement[_displayMode.getValue()].get(iii).exist()) {
//Log.debug("return " + iii);
// Log.debug("return " + iii);
return iii;
} else {
return 0;
@ -360,19 +407,21 @@ public class ResourceTexturedFont extends ResourceTexture2 {
}
}
if (addGlyph(_charcode) == true) {
// TODO : This does not work due to the fact that the update of open GL is not done in the context main cycle !!!
// TODO : This does not work due to the fact that the update of open GL is not
// done in the context main cycle !!!
Ewol.getContext().forceRedrawAll();
}
return 0;
};
/**
* @brief The wrapping mode is used to prevent the non existance of a specific mode.
* For exemple when a blod mode does not exist, this resend a regular mode.
* @brief The wrapping mode is used to prevent the non existance of a specific
* mode. For exemple when a blod mode does not exist, this resend a
* regular mode.
* @param[in] _source The requested mode.
* @return the best mode we have in stock.
*/
private FontMode getWrappingMode(final FontMode _source) {
public FontMode getWrappingMode(final FontMode _source) {
return this.modeWraping[_source.getValue()];
}
}