package br.com.etyllica.layer;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import br.com.etyllica.core.graphics.Graphics;
import br.com.etyllica.loader.FontLoader;
/**
*
* @author yuripourre
*
*/
public class TextLayer extends ImageLayer {
private String text;
private int style = Font.PLAIN;
private float size = 16;
private Font font = null;
private String fontName = "";
private Color color = Color.BLACK;
private Color borderColor = Color.GRAY;
private boolean border = false;
private float borderWidth = 4f;
private boolean antiAliased = true;
private boolean fractionalMetrics = false;
public TextLayer(String text) {
this(0,0,text);
}
public TextLayer(int x, int y, String text) {
super(x,y);
setText(text);
}
public int getStyle() {
return style;
}
public void setStyle(int style) {
this.style = style;
}
public float getSize() {
return size;
}
public void setSize(float size) {
this.size = size;
}
public String getFontName() {
return fontName;
}
public void setFontName(String fontName) {
this.fontName = fontName;
this.font = FontLoader.getInstance().loadFont(fontName).deriveFont(style, size);
}
@Override
public void simpleDraw(Graphics g, int x, int y) {
if (font == null) {
font = g.getFont().deriveFont(style, size);
}
g.setFont(font);
if (!border) {
g.setColor(color);
g.drawString(text, x, y);
} else {
FontRenderContext frc = new FontRenderContext(null, antiAliased, fractionalMetrics);
TextLayout layout = new TextLayout(text, font, frc);
Shape sha = layout.getOutline(AffineTransform.getTranslateInstance(x,y));
g.setStroke(new BasicStroke(borderWidth));
g.setColor(borderColor);
g.draw(sha);
g.setColor(color);
g.fill(sha);
}
}
@Override
public AffineTransform getTransform() {
if(font == null)
return AffineTransform.getScaleInstance(1, 1);
AffineTransform transform = new AffineTransform();
FontRenderContext frc = new FontRenderContext(null, antiAliased, fractionalMetrics);
TextLayout layout = new TextLayout(text, font, frc);
Rectangle2D bounds = layout.getBounds();
float height = size;
float width = (float) Math.ceil(bounds.getWidth());
if(angle != 0) {
transform.concatenate(AffineTransform.getRotateInstance(Math.toRadians(angle),x+w/2, y+h/2));
}
if(scaleX != 1 || scaleY != 1) {
double sw = width*scaleX;
double sh = height*scaleY;
double dx = sw/2-width/2;
double dy = sh/2-height/2;
transform.translate(x-width/2-dx, y-height/2+dy);
AffineTransform tr2 = new AffineTransform();
tr2.translate(width/2, height/2);
tr2.scale(scaleX, scaleY);
tr2.translate(-x, -y);
transform.concatenate(tr2);
}
return transform;
}
public void setColor(int r, int g, int b) {
color = new Color(r%256,g%256,b%256);
}
public Color getBorderColor() {
return borderColor;
}
public void setBorderColor(Color borderColor) {
this.borderColor = borderColor;
}
public Color getColor() {
return color;
}
public void setText(String text) {
if(!text.isEmpty()) {
this.text = text;
computeBoundingBox();
}else{
this.text = " ";
}
}
private void computeBoundingBox() {
Font font;
if(this.font!=null) {
font = this.font;
}else{
font = new Font(Font.DIALOG, Font.PLAIN, (int)size);
}
//Compute Bounding box
FontRenderContext frc = new FontRenderContext(null, antiAliased, fractionalMetrics);
TextLayout layout = new TextLayout(text, font, frc);
Rectangle2D bounds = layout.getBounds();
this.h = (int)size;
this.w = (int)Math.ceil(bounds.getWidth());
}
public void setBorder(boolean border) {
this.border = border;
}
public void setColor(Color color) {
this.color = color;
}
public boolean isBorder() {
return border;
}
public String getText() {
return text;
}
public boolean isAntiAliased() {
return antiAliased;
}
public void setAntiAliased(boolean antiAliased) {
this.antiAliased = antiAliased;
}
public boolean isFractionalMetrics() {
return fractionalMetrics;
}
public void setFractionalMetrics(boolean fractionalMetrics) {
this.fractionalMetrics = fractionalMetrics;
}
public float getBorderWidth() {
return borderWidth;
}
public void setBorderWidth(float borderWidth) {
this.borderWidth = borderWidth;
}
}