package k8.text;
import k8.k8;
import k8.SceneNode;
import k8.primitive.Triangle;
import k8.util.LinkedList;
/** Represents a text layout. */
public class Text extends SceneNode
{
public static Font newTextFont;
private static LinkedList.Node<Triangle> curr;
/** Sets the default font assigned to new Text instances. */
public static void setDefaultFont(String font)
{
try
{
newTextFont = new Font(font);
}
catch (Exception e)
{
k8.logger.warning("Can't set default Text Font to " + font);
k8.logger.warning(e.getMessage());
}
}
private String text;
private Font font;
private float scale;
private float x, w, a, d;
private int c, l;
private GlyphMetrics gm;
private LinkedList<Triangle> triangles;
/**
* Creates a new instance of Text.
*
* @throws Exception
*/
public Text()
{
this("");
}
/**
* Creates a new instance of Text.
*
* @throws Exception
*/
public Text(String text)
{
this(text, 1);
}
/**
* Creates a new instance of Text.
*
* @throws Exception
*/
public Text(String text, float scale)
{
if (newTextFont == null)
{
setDefaultFont("/k8/text/Default.png");
}
this.font = newTextFont;
triangles = new LinkedList<Triangle>();
setScale(scale);
setText(text);
}
public void setFont(Font font)
{
this.font = font;
update();
}
public void setText(int text)
{
setText(Integer.toString(text));
}
public void setText(long text)
{
setText(Long.toString(text));
}
public void setText(String text)
{
this.text = text;
if (text != null && text.length() > 0)
{
update();
}
}
public void setScale(float scale)
{
this.scale = scale;
}
/** Updates/Adds/Removes triangles to display a change in text. */
private void update()
{
// Avoid updating when there is no font or text
if (font == null || text == null || text.equals(""))
return;
// Setup counters
x = 0;
c = 0;
l = text.length();
// Reuse previous triangles
curr = null;
while ((curr = triangles.next(curr)) != null)
{
// Hide remaining triangles
if (c == l)
{
curr.item.setVisible(false);
continue;
}
// Reuse current and next triangle for current character
gm = font.getGlyphMetrics(text.codePointAt(c));
// Apply scaling
w = gm.width * scale;
a = gm.ascent * scale;
d = gm.descent * scale;
// ._
// | /
// |/
curr.item.setVertices(x, a, 0, x, d, 0, x + w, a, 0);
curr.item.setTexture(gm.u1, gm.v1, gm.u1, gm.v2, gm.u2, gm.v1);
curr.item.setVisible(true);
// Advance to next Triangle
curr = triangles.next(curr);
// ./|
// /_|
curr.item.setVertices(x, d, 0, x + w, d, 0, x + w, a, 0);
curr.item.setTexture(gm.u1, gm.v2, gm.u2, gm.v2, gm.u2, gm.v1);
curr.item.setVisible(true);
// Advance next position width of current character
x += w;
c++;
}
// Create new triangles, when needed, for remaining characters
while (c < l)
{
// Get the GlyphMetrics for the current character
gm = font.getGlyphMetrics(text.codePointAt(c));
// Apply scaling
w = gm.width * scale;
a = gm.ascent * scale;
d = gm.descent * scale;
// Create two new triangles, set attributes and add
// ._
// | /
// |/
Triangle t = new Triangle();
t.setTexture(font);
t.setVertices(x, a, 0, x, d, 0, x + w, a, 0);
t.setTexture(gm.u1, gm.v1, gm.u1, gm.v2, gm.u2, gm.v1);
this.add(t);
triangles.append(t);
// ./|
// /_|
t = new Triangle();
t.setTexture(font);
t.setVertices(x, d, 0, x + w, d, 0, x + w, a, 0);
t.setTexture(gm.u1, gm.v2, gm.u2, gm.v2, gm.u2, gm.v1);
this.add(t);
triangles.append(t);
// Advance next position width of current character
x += w;
c++;
}
}
@Override
protected void transform()
{
// TODO Auto-generated method stub
}
}