Subversion Repositories AndroidProjects

Rev

Rev 1051 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.gebauz.bauzoid.graphics;

import java.util.Hashtable;

import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.gebauz.bauzoid.graphics.sprite.Sprite;
import com.gebauz.bauzoid.graphics.sprite.SpriteInstance;
import com.gebauz.bauzoid.graphics.sprite.TileBatch;
import com.gebauz.bauzoid.math.Vector4;

public class Font extends GraphicsObject
{
        public static final Vector4 DEFAULT_COLOR = new Vector4(1, 1, 1, 1);
       
        public static class KerningPair
        {
                public char first;
                public char second;
               
                public KerningPair(char a, char b)
                {
                        first = a;
                        second = b;
                }
               
                @Override
                public boolean equals(Object other)
                {
                    // Not strictly necessary, but often a good optimization
                    if (this == other)
                      return true;
                   
                    if (!(other instanceof KerningPair))
                      return false;
                   
                    KerningPair p = (KerningPair)other;
                   
                    return ((first == p.first) && (second == p.second));
                }
               
                @Override
                public int hashCode()
                {
                        return (first * 256) + second;                 
                }
        }
       
        public static class CharacterInfo
        {
                private char mCharacter;
                private SpriteInstance mSpriteInstance = null;
               
                public float offsetX = 0;
                public float offsetY = 0;
               
                public float width;
       
                public CharacterInfo(char c)
                {
                        mCharacter = c;
                }
               
                public final char getCharacter()
                {
                        return mCharacter;
                }
               
                public void setSpriteInstance(SpriteInstance instance)
                {
                        mSpriteInstance = instance;
                }
               
                public final SpriteInstance getSpriteInstance()
                {
                        return mSpriteInstance;
                }
               
                public void render()
                {
                        if (mSpriteInstance == null)
                                return;
                       
                        mSpriteInstance.render();
                }
        }
       
        private CharacterInfo[] mCharacters = null;
        private float mAscent = 0.0f;
        private float mGlobalMultiplier = 2.0f;
        private Sprite mSprite = null;
       
        private Hashtable<KerningPair, Integer> mKernings = new Hashtable<KerningPair, Integer>();
       
        /** The y difference of a line break in multiples of line height. */
        private float mLineBreakFactor = 1.0f;

        public Font(Graphics graphics)
        {
                super(graphics);

        }
       
        public void dispose()
        {
                mCharacters = null;            
        }
       
        public void setAscent(float ascent)
        {
                mAscent = ascent;
        }
       
        public void setCharacters(CharacterInfo[] characters)
        {
                mCharacters = characters;
        }
       
        public void setSprite(Sprite sprite)
        {
                mSprite = sprite;
        }
       
        public void setGlobalMultiplier(float multiplier)
        {
                mGlobalMultiplier = multiplier;
        }
       
        public void drawText(String text, float x, float y, float scale)
        {
                drawText(text, x, y, DEFAULT_COLOR, scale);
        }
       
        public void drawText(String text, float x, float y)
        {
                drawText(text, x, y, DEFAULT_COLOR);
        }
       
        public void drawText(String text, float x, float y, Vector4 color)
        {
                drawText(text, x, y, color, 1.0f);
        }
       
        public void drawTextDirect(String text, float x, float y, Vector4 color, float scale)
        {
                float posX = x;
                float posY = y;
               
                for (int i = 0; i < text.length(); i++)
                {
                        if (text.charAt(i) == '\n')
                        {
                                posY += mAscent * mLineBreakFactor * scale;
                                posX = x;
                                continue;
                        }
                       
                        int n = getCharacterIndexNoCase(text.charAt(i));
                        if (n == -1)
                        {
                                continue;
                        }
                       
                        CharacterInfo c = mCharacters[n];
                       
                        int kerning = 0;
                        if (i < (text.length()-1))
                        {
                                // apply kerning if any
                                char first = c.getCharacter();
                                char second = text.charAt(i+1);
                               
                                kerning = getKerning(first, second);
                        }
                        if (c.mSpriteInstance != null)
                        {
                                float texW = c.mSpriteInstance.getSprite().getTextureWidth();
                                float texH = c.mSpriteInstance.getSprite().getTextureHeight();
                                c.mSpriteInstance.transform.x = posX;
                                c.mSpriteInstance.transform.y = posY;
                                c.mSpriteInstance.color = color;
                                c.mSpriteInstance.transform.w = c.mSpriteInstance.getSpriteRegion().getWidth() * texW * scale * mGlobalMultiplier;
                                c.mSpriteInstance.transform.h = c.mSpriteInstance.getSpriteRegion().getHeight() * texH * scale * mGlobalMultiplier;
                                //c.mSpriteInstance.param.w = mSprite.getRegionWidth(c.mSpriteInstance.getRegionIndex()) * scale * mGlobalMultiplier;
                                //c.mSpriteInstance.param.h = mSprite.getRegionHeight(c.mSpriteInstance.getRegionIndex()) * scale * mGlobalMultiplier;
                                c.mSpriteInstance.transform.pivotX = 0;
                                c.mSpriteInstance.transform.pivotY = 0;
                                c.mSpriteInstance.render();
                        }
                       
                        posX += c.width * scale + kerning - c.offsetX;
                }
        }

        public void drawText(String text, float x, float y, Vector4 color, float scale)
        {
                float posX = x;
                float posY = y;
               
                TileBatch batch = getGraphics().getBatch();
               
                batch.begin();
               
                for (int i = 0; i < text.length(); i++)
                {
                        if (text.charAt(i) == '\n')
                        {
                                posY += mAscent * mLineBreakFactor * scale;
                                posX = x;
                                continue;
                        }
                       
                        int n = getCharacterIndexNoCase(text.charAt(i));
                        if (n == -1)
                        {
                                continue;
                        }
                       
                        CharacterInfo c = mCharacters[n];
                       
                        int kerning = 0;
                        if (i < (text.length()-1))
                        {
                                // apply kerning if any
                                char first = c.getCharacter();
                                char second = text.charAt(i+1);
                               
                                kerning = getKerning(first, second);
                        }
                        if (c.mSpriteInstance != null)
                        {                      
                                float texW = c.mSpriteInstance.getSprite().getTextureWidth();
                                float texH = c.mSpriteInstance.getSprite().getTextureHeight();
                                c.mSpriteInstance.transform.x = posX;
                                c.mSpriteInstance.transform.y = posY;
                                c.mSpriteInstance.color = color;
                                c.mSpriteInstance.transform.w = c.mSpriteInstance.getSpriteRegion().getWidth() * texW * scale * mGlobalMultiplier;
                                c.mSpriteInstance.transform.h = c.mSpriteInstance.getSpriteRegion().getHeight() * texH * scale * mGlobalMultiplier;
                                //c.mSpriteInstance.param.w = mSprite.getRegionWidth(c.mSpriteInstance.getRegionIndex()) * scale * mGlobalMultiplier;
                                //c.mSpriteInstance.param.h = mSprite.getRegionHeight(c.mSpriteInstance.getRegionIndex()) * scale * mGlobalMultiplier;
                                c.mSpriteInstance.transform.pivotX = 0;
                                c.mSpriteInstance.transform.pivotY = 0;
                       
                                batch.drawSprite(c.mSpriteInstance);
                        }
                       
                        posX += c.width * scale + kerning - c.offsetX;
                }
               
                batch.end();
        }
       
        public float getTextWidth(String text, float scale)
        {
                float maxWidth = 0;
                float width = 0;
                float posX = 0;
               
                for (int i = 0; i < text.length(); i++)
                {
                        if (text.charAt(i) == '\n')
                        {
                                posX = 0;
                                continue;
                        }
                       
                        int n = getCharacterIndexNoCase(text.charAt(i));
                        if (n == -1)
                        {
                                continue;
                        }
                       
                        CharacterInfo c = mCharacters[n];
                        int kerning = 0;
                        if (i < (text.length()-1))
                        {
                                // apply kerning if any
                                char first = c.getCharacter();
                                char second = text.charAt(i+1);
                               
                                kerning = getKerning(first, second);
                        }
                       
                        width = posX + c.width * scale;
                       
                        if (maxWidth < width)
                        {
                                maxWidth = width;
                        }
                       
                        posX += c.width * scale + kerning - c.offsetX;
                }
               
                return maxWidth;
        }
       
        public float getTextHeight(String text, float scale)
        {
                float maxHeight = 0;
                float posY = 0;
               
               
               
                for (int i = 0; i < text.length(); i++)
                {
                        if (text.charAt(i) == '\n')
                        {
                                posY += mAscent * mLineBreakFactor * scale;
                                continue;
                        }
                       
                        int n = getCharacterIndexNoCase(text.charAt(i));
                        if (n == -1)
                        {
                                continue;
                        }
                       
                        float charHeight = this.mAscent * scale;

                        if ((posY + charHeight) > maxHeight)
                        {
                                maxHeight = posY + charHeight;
                        }
                }
               
                return maxHeight;
        }
       
        public int getCharacterIndex(char c)
        {
                for (int i = 0; i < mCharacters.length; i++)
                {
                        if (mCharacters[i].getCharacter() == c)
                                return i;
                }
               
                return -1;
        }
       
        public int getCharacterIndexNoCase(char c)
        {
                int n = getCharacterIndex(c);
                if (n == -1)
                {
                        n = getCharacterIndex(Character.toLowerCase(c));
                        if (n == -1)
                        {
                                n = getCharacterIndex(Character.toUpperCase(c));
                        }
                }
                return n;
        }
       
        public CharacterInfo getCharacter(char c)
        {
                int i = getCharacterIndex(c);
               
                if (i != -1)
                        return mCharacters[i];
               
                return null;
        }
       
        public void setKerning(char first, char second, int value)
        {
                mKernings.put(new KerningPair(first, second), value);
        }
       
        public int getKerning(char first, char second)
        {
                Integer value = mKernings.get(new KerningPair(first, second));
               
                if (value == null)
                        return 0;
               
                return value;
        }
       
        public void setFiltering(boolean filter)
        {
                /*
                // HACK: should use own texture class
                if (filter)
                        getGraphics().renderStates.getTextureStage(0).setTextureFilter(mSprite.getTexture(), TextureFilter.Linear, TextureFilter.Linear);
                else
                        getGraphics().renderStates.getTextureStage(0).setTextureFilter(mSprite.getTexture(), TextureFilter.Nearest, TextureFilter.Nearest);*/

               
                if (filter)
                        mSprite.getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
                else
                        mSprite.getTexture().setFilter(TextureFilter.Nearest, TextureFilter.Nearest);
        }
       
        public final void setLineBreak(float multiple) { mLineBreakFactor = multiple; }
        public final float getLineBreak() { return mLineBreakFactor; }
       
       
}