/***********************************************************************
* mt4j Copyright (c) 2008 - 2009 C.Ruff, Fraunhofer-Gesellschaft All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
***********************************************************************/
package org.mt4j.components.visibleComponents.font;
import java.nio.FloatBuffer;
import org.mt4j.components.bounds.IBoundingShape;
import org.mt4j.components.visibleComponents.shapes.MTRectangle;
import org.mt4j.util.MT4jSettings;
import org.mt4j.util.font.IFontCharacter;
import org.mt4j.util.font.ITextureFontCharacter;
import org.mt4j.util.math.Vertex;
import org.mt4j.util.opengl.GL10;
import org.mt4j.util.opengl.GLTexture;
import org.mt4j.util.opengl.GLTexture.EXPANSION_FILTER;
import org.mt4j.util.opengl.GLTexture.SHRINKAGE_FILTER;
import org.mt4j.util.opengl.GLTexture.WRAP_MODE;
import processing.core.PApplet;
import processing.core.PGraphics;
import processing.core.PImage;
/**
* The Class BitmapFontCharacter.
* @author Christopher Ruff
*/
public class BitmapFontCharacter extends MTRectangle implements IFontCharacter, ITextureFontCharacter {
/** The unicode. */
private String unicode;
/** The horizontal dist. */
private int horizontalDist;
/** The left offset. */
private int leftOffset;
/**
* Instantiates a new bitmap font character.
* @param applet the applet
* @param texture the texture
* @param unicode the unicode
* @param leftOffset the left offset
* @param topOffset the top offset
* @param horizontalAdvance the horizontal advance
*/
public BitmapFontCharacter(PApplet applet, PImage texture, String unicode, int leftOffset, int topOffset, int horizontalAdvance) {
super(applet, new Vertex(leftOffset, topOffset,0), texture.width, texture.height);
this.setTexture(texture);
this.setTextureEnabled(true);
this.leftOffset = leftOffset;
this.horizontalDist = horizontalAdvance;
this.unicode = unicode;
this.setNoStroke(true);
this.setPickable(false);
if (MT4jSettings.getInstance().isOpenGlMode()){
//Set the texture to be non-repeating but clamping to the border to avoid artefacts
PImage tex = this.getTexture();
if (tex instanceof GLTexture) {
GLTexture glTex = (GLTexture) tex;
// glTex.setWrap(GL.GL_CLAMP, GL.GL_CLAMP);
// glTex.setWrap(GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
glTex.setWrapMode(WRAP_MODE.CLAMP_TO_EDGE, WRAP_MODE.CLAMP_TO_EDGE);
// glTex.setFilter(SHRINKAGE_FILTER.Trilinear, EXPANSION_FILTER.Bilinear);
glTex.setFilter(SHRINKAGE_FILTER.BilinearNoMipMaps, EXPANSION_FILTER.Bilinear);
// glTex.setFilter(SHRINKAGE_FILTER.NearestNeighborNoMipMaps, EXPANSION_FILTER.NearestNeighbor);
// glTex.setFilter(SHRINKAGE_FILTER.BilinearNoMipMaps, EXPANSION_FILTER.NearestNeighbor);
}
}
}
@Override
public void drawComponent(PGraphics g) {
//Draw the shape
if (MT4jSettings.getInstance().isOpenGlMode() && this.isUseDirectGL()){
super.drawComponent(g);
}else{ //Draw with pure proccessing commands...
g.strokeWeight(this.getStrokeWeight());
if (this.isNoStroke())
g.noStroke();
drawWithProcessing(g);
if (/*MT4jSettings.getInstance().isOpenGlMode() &&*/ this.isDrawSmooth())
g.noSmooth(); //because of tesselation bug/lines visibile in shapes
}
}
/* (non-Javadoc)
* @see org.mt4j.components.visibleComponents.font.IFontCharacter#drawComponent(javax.media.opengl.GL)
*/
//@Override
public void drawComponent(GL10 gl) {
// this.drawPureGl(gl);
// /*
if (MT4jSettings.getInstance().isOpenGlMode()){
// if (this.isUseDisplayList() && this.getGeometryInfo().getDisplayListIDs()[0] != -1){
//// gl.glCallList(this.getGeometryInfo().getDisplayListIDs()[0]);
// ((GL11Plus)gl).glCallList(this.getGeometryInfo().getDisplayListIDs()[0]);
//// gl.glCallList(this.getGeometryInfo().getDisplayListIDs()[1]); //Outline rectangle
// }else{
this.drawPureGl(gl);
// }
}
// */
}
@Override
public void generateAndUseDisplayLists() {
// super.generateAndUseDisplayLists();
// System.out.println("display list not supported in: " + this.getClass().getName());
}
@Override
public void setUseDisplayList(boolean useDisplayList) {
// super.setUseDisplayList(useDisplayList);
// System.out.println("display list not supported in: " + this.getClass().getName());
}
@Override
protected void drawPureGl(GL10 gl){
if (!this.isNoFill()){
////
//Get display array/buffer pointers
FloatBuffer tbuff = this.getGeometryInfo().getTexBuff();
FloatBuffer vertBuff = this.getGeometryInfo().getVertBuff();
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertBuff);
// tex.getTextureTarget has to be the same as used in font.prepareBatchRenderGL() !!
// we assume its GL_TEXTURE_2D
GLTexture tex = (GLTexture)this.getTexture();
int textureTarget = tex.getTextureTarget();
gl.glBindTexture(textureTarget, tex.getTextureID());
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, tbuff);
gl.glDrawArrays(this.getFillDrawMode(), 0, vertBuff.capacity()/3);
////
}
}
// @Override
// protected void drawPureGl(GL10 gl){
// GL11 gl11 = GraphicsUtil.getGL11();
//
//// /*
// //Get display array/buffer pointers
// FloatBuffer tbuff = this.getGeometryInfo().getTexBuff();
// FloatBuffer vertBuff = this.getGeometryInfo().getVertBuff();
//
// //Enable Pointers, set vertex array pointer
// gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// if (this.isUseVBOs()){//Vertices
//// gl.glBindBuffer(GL.GL_ARRAY_BUFFER, this.getGeometryInfo().getVBOVerticesName());
//// gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);
// gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, this.getGeometryInfo().getVBOVerticesName());
// gl11.glVertexPointer(3, GL10.GL_FLOAT, 0, 0);
// }else{
// gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertBuff);
// }
//
// //Default texture target
// int textureTarget = GL10.GL_TEXTURE_2D;
//
// /////// DRAW SHAPE ///////
// if (!this.isNoFill()){
// boolean textureDrawn = false;
// if (this.isTextureEnabled()
// && this.getTexture() != null
// && this.getTexture() instanceof GLTexture) //Bad for performance?
// {
// GLTexture tex = (GLTexture)this.getTexture();
// textureTarget = tex.getTextureTarget();
//
// //tells opengl which texture to reference in following calls from now on!
// //the first parameter is eigher GL.GL_TEXTURE_2D or ..1D
// gl.glEnable(textureTarget);
// gl.glBindTexture(textureTarget, tex.getTextureID());
//
// gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
//
// if (this.isUseVBOs()){//Texture
//// gl.glBindBuffer(GL.GL_ARRAY_BUFFER, this.getGeometryInfo().getVBOTextureName());
//// gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0);
// gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, this.getGeometryInfo().getVBOTextureName());
// gl11.glTexCoordPointer(2, GL10.GL_FLOAT, 0, 0);
// }else
// gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, tbuff);
//
// textureDrawn = true;
// }
//
// //Normals
// if (this.getGeometryInfo().isContainsNormals()){
// gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
// if (this.isUseVBOs()){
//// gl.glBindBuffer(GL.GL_ARRAY_BUFFER, this.getGeometryInfo().getVBONormalsName());
//// gl.glNormalPointer(GL.GL_FLOAT, 0, 0);
// gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, this.getGeometryInfo().getVBONormalsName());
// gl11.glNormalPointer(GL10.GL_FLOAT, 0, 0);
// }else{
// gl.glNormalPointer(GL10.GL_FLOAT, 0, this.getGeometryInfo().getNormalsBuff());
// }
// }
//
// gl.glDrawArrays(this.getFillDrawMode(), 0, vertBuff.capacity()/3);
//
// if (this.getGeometryInfo().isContainsNormals()){
// gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
// }
//
// if (textureDrawn){
// gl.glBindTexture(textureTarget, 0);//Unbind texture
// gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// gl.glDisable(textureTarget); //weiter nach unten?
// }
// }
// gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
// //TEST
// if (this.isUseVBOs()){
//// gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
//// gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
// gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
// gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, 0);
// }
//// */
// }
@Override
protected void setDefaultGestureActions() {
//no gestures
}
/* (non-Javadoc)
* @see org.mt4j.components.visibleComponents.shapes.MTRectangle#computeDefaultBounds()
*/
//@Override
protected IBoundingShape computeDefaultBounds() {
//We assume that font characters never get picked or anything
//and hope the creation speeds up by not calculating a bounding shape
return null;
}
/* (non-Javadoc)
* @see org.mt4j.components.visibleComponents.font.IFontCharacter#getHorizontalDist()
*/
//@Override
public int getHorizontalDist() {
return this.horizontalDist;
}
/**
* Sets the horizontal dist.
*
* @param horizontalDist the new horizontal dist
*/
public void setHorizontalDist(int horizontalDist) {
this.horizontalDist = horizontalDist;
}
/* (non-Javadoc)
* @see org.mt4j.components.visibleComponents.font.IFontCharacter#getUnicode()
*/
//@Override
public String getUnicode() {
return this.unicode;
}
/**
* Sets the unicode.
*
* @param unicode the new unicode
*/
public void setUnicode(String unicode) {
this.unicode = unicode;
}
public int getLeftOffset() {
return this.leftOffset;
}
//FIXME TEST
public void setTextureFiltered(boolean scalable) {
if (MT4jSettings.getInstance().isOpenGlMode()){
PImage tex = this.getTexture();
if (tex instanceof GLTexture) {
GLTexture glTex = (GLTexture) tex;
//normally we would use GL_LINEAR as magnification filter but sometimes
//small text is too filtered and smudged so we use NEAREST -> but this makes
//scaled text very ugly and pixelated..
if (scalable){
// glTex.setFilter(GL.GL_LINEAR, GL.GL_LINEAR);
glTex.setFilter(SHRINKAGE_FILTER.BilinearNoMipMaps, EXPANSION_FILTER.Bilinear);
}else{
// glTex.setFilter(GL.GL_LINEAR, GL.GL_NEAREST);
glTex.setFilter(SHRINKAGE_FILTER.BilinearNoMipMaps, EXPANSION_FILTER.NearestNeighbor);
}
}
}
}
@Override
public int getKerning(String character) {
// TODO Auto-generated method stub
return 0;
}
}