Subversion Repositories AndroidProjects

Rev

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

package com.gebauz.Bauzoid.graphics;

import java.util.Vector;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Texture;
import com.gebauz.Bauzoid.app.Consts;
import com.gebauz.Bauzoid.file.FileUtil;
import com.gebauz.Bauzoid.graphics.sprite.AtlasSprite;
import com.gebauz.Bauzoid.graphics.sprite.SpriteRegion;
import com.gebauz.Bauzoid.parser.ScanException;
import com.gebauz.Bauzoid.parser.Tokenizer;

public class FontUtil
{
        public static final String LOG_TAG = Consts.LOG_TAG + ":FontUtil";
        public static boolean verbose = true;
       
        private static class CharacterRect
        {
                public float x;
                public float y;
                public float w;
                public float h;
               
                public CharacterRect(float _x, float _y, float _w, float _h)
                {
                        x = _x;
                        y = _y;
                        w = _w;
                        h = _h;
                }
        }
       
        private static class CharacterOffset
        {
                public float x;
                public float y;
               
                public CharacterOffset(float _x, float _y)
                {
                        x = _x;
                        y = _y;
                }
        }
       
        private FontUtil() {}
       
        public static void log(String tag, String msg)
        {
                if (verbose)
                        Gdx.app.log(tag, msg);                 
        }
       
        public static Font createFontFromFile(Graphics graphics, FileHandle file)
        {
                String fileContents = file.readString();
               
                Vector<Character> charList = null;
                Vector<Float> widthList = null;
                Vector<CharacterRect> rectList = null;
                Vector<CharacterOffset> offsetList = null;
       
                Font font = new Font(graphics);
                Texture texture = null;
               
                float multiplier = 1.0f;
               
                try
                {
                        Tokenizer tokenizer = new Tokenizer(fileContents);
                        tokenizer.setStringDelimiter(new char[] {'\'', '"'} );
                       
                        while (!tokenizer.checkNoMoreTokens())
                        {
                                String identifier = tokenizer.readIdentifier();
                               
                                if (identifier.equalsIgnoreCase("Define"))
                                {
                                        // Define
                                        String define = tokenizer.readIdentifier();
                                       
                                        if (define.equalsIgnoreCase("CharList"))
                                        {
                                                charList = parseCharList(tokenizer);
                                        }
                                        else if (define.equalsIgnoreCase("WidthList"))
                                        {
                                                widthList = parseWidthList(tokenizer);
                                        }
                                        else if (define.equalsIgnoreCase("RectList"))
                                        {
                                                rectList = parseRectList(tokenizer);
                                        }
                                        else if (define.equalsIgnoreCase("OffsetList"))
                                        {
                                                offsetList = parseOffsetList(tokenizer);
                                        }
                                        tokenizer.readToken(";");
                                }
                                else if (identifier.equalsIgnoreCase("CreateLayer"))
                                {
                                        tokenizer.readIdentifier();
                                        tokenizer.readToken(";");
                                }
                                else if (identifier.equalsIgnoreCase("LayerSetImage"))
                                {
                                        tokenizer.readIdentifier();
                                        // TODO: actually extract path from given file
                                        String filename = FileUtil.extractPath(file.path()) + "/" + tokenizer.readString() + ".png";
                                       
                                        texture = new Texture(Gdx.files.internal(filename));
                                       
                                        tokenizer.readToken(";");
                                }
                                else if (identifier.equalsIgnoreCase("LayerRegionMultiplier"))
                                {
                                        tokenizer.readIdentifier();
                                       
                                        multiplier = tokenizer.readNumber();
                                        tokenizer.readToken(";");
                                }
                                else if (identifier.equalsIgnoreCase("LayerSetAscent"))
                                {
                                        tokenizer.readIdentifier();
                                        float ascent = tokenizer.readNumber();
                                        font.setAscent(ascent);
                                        tokenizer.readToken(";");
                                }
                                else if (identifier.equalsIgnoreCase("LayerSetCharWidths"))
                                {
                                        tokenizer.readIdentifier();
                                        if (tokenizer.checkIdentifier())
                                        {
                                                tokenizer.readIdentifier();
                                                tokenizer.readIdentifier();
                                        }
                                        else if (tokenizer.checkToken("("))
                                        {
                                                Vector<Character> charListExtra = parseCharList(tokenizer);
                                                Vector<Float> widthListExtra = parseWidthList(tokenizer);
                                               
                                                charList.addAll(charListExtra);
                                                widthList.addAll(widthListExtra);
                                        }
                                        tokenizer.readToken(";");
                                }
                                else if (identifier.equalsIgnoreCase("LayerSetImageMap"))
                                {
                                        tokenizer.readIdentifier();
                                        tokenizer.readIdentifier();
                                        tokenizer.readIdentifier();
                                        tokenizer.readToken(";");
                                }
                                else if (identifier.equalsIgnoreCase("LayerSetCharOffsets"))
                                {
                                        tokenizer.readIdentifier();
                                        tokenizer.readIdentifier();
                                        tokenizer.readIdentifier();
                                        tokenizer.readToken(";");
                                }              
                                else if (identifier.equalsIgnoreCase("LayerSetAscentPadding"))
                                {
                                        tokenizer.readIdentifier();
                                        tokenizer.readNumber();
                                        tokenizer.readToken(";");
                                }              
                                else if (identifier.equalsIgnoreCase("LayerSetLineSpacingOffset"))
                                {
                                        tokenizer.readIdentifier();
                                        tokenizer.readNumber();
                                        tokenizer.readToken(";");
                                }              
                                else if (identifier.equalsIgnoreCase("LayerSetPointSize"))
                                {
                                        tokenizer.readIdentifier();
                                        tokenizer.readNumber();
                                        tokenizer.readToken(";");
                                }              
                                else if (identifier.equalsIgnoreCase("SetDefaultPointSize"))
                                {
                                        tokenizer.readNumber();
                                        tokenizer.readToken(";");
                                }
                        }
                       
                }
                catch (ScanException ex)
                {
                        ex.log(LOG_TAG);
                }
               
                // Build font
                Font.CharacterInfo[] characters = new Font.CharacterInfo[charList.size()];
                SpriteRegion[] regions = new SpriteRegion[rectList.size()];
               
                for (int i = 0; i < characters.length; i++)
                {
                        characters[i] = new Font.CharacterInfo(charList.elementAt(i));
                       
                        characters[i].width = widthList.elementAt(i);
                       
                        if (i < offsetList.size())
                        {
                                characters[i].offsetX = offsetList.elementAt(i).x;
                                characters[i].offsetY = offsetList.elementAt(i).y;
                        }
                       
                        if (i < rectList.size())
                        {
                                CharacterRect rect = rectList.elementAt(i);
                               
                                /*characters[i].texX = rectList.elementAt(i).x;
                                characters[i].texY = rectList.elementAt(i).y;
                                characters[i].texW = rectList.elementAt(i).w;
                                characters[i].texH = rectList.elementAt(i).h;*/

                                regions[i] = new SpriteRegion(texture, rect.x / multiplier, rect.y / multiplier, rect.w / multiplier, rect.h / multiplier);
                        }
                }
               
                AtlasSprite sprite = new AtlasSprite(graphics, texture, regions);
               
                for (int i = 0; i < regions.length; i++)
                {
                        characters[i].setSpriteInstance(sprite.createSpriteInstance(i));
                }
               
                font.setCharacters(characters);
                font.setSprite(sprite);        
                font.setGlobalMultiplier(multiplier);
               
                return font;
        }
       
        private static Vector<Character> parseCharList(Tokenizer t) throws ScanException
        {
                Vector<Character> charList = new Vector<Character>();
               
                t.readToken("(");
               
                while (!t.checkToken(")"))
                {
                        String character = t.readString();
                       
                        if (character.length() > 1)
                                throw new ScanException("Character can only have length 1!", t.getSurroundings());
                       
                        charList.add(character.charAt(0));
                       
                        if (t.checkToken(")"))
                                break;
                       
                        t.readToken(",");
                }                              
               
                t.readToken(")");
               
                return charList;
        }
       
        private static Vector<Float> parseWidthList(Tokenizer t) throws ScanException
        {
                Vector<Float> widthList = new Vector<Float>();
               
                t.readToken("(");
               
                while (!t.checkToken(")"))
                {
                        float width = t.readNumber();
                       
                        widthList.add(width);
                       
                        if (t.checkToken(")"))
                                break;
                       
                        //Gdx.app.log(LOG_TAG, "[" + width + "]");
                       
                        t.readToken(",");
                }                              
               
                t.readToken(")");
               
                return widthList;
        }
       
        private static Vector<CharacterRect> parseRectList(Tokenizer t) throws ScanException
        {
                Vector<CharacterRect> rectList = new Vector<CharacterRect>();
               
                t.readToken("(");
               
                while (t.checkToken("("))
                {
                        t.readToken("(");
                       
                        float x = t.readNumber();
                        t.readToken(",");
                        float y = t.readNumber();
                        t.readToken(",");
                        float w = t.readNumber();
                        t.readToken(",");
                        float h = t.readNumber();
                       
                        rectList.add(new CharacterRect(x, y, w, h));
                       
                        t.readToken(")");
                       
                        if (!t.checkToken(","))
                                break;
                       
                        t.readToken(",");
                }              
               
                if (!t.checkToken(")"))
                        throw new ScanException("Syntax error in RectList!", t.getSurroundings());
               
                t.readToken(")");
               
                return rectList;
        }
       
        private static Vector<CharacterOffset> parseOffsetList(Tokenizer t) throws ScanException
        {
                Vector<CharacterOffset> offsetList = new Vector<CharacterOffset>();
               
                t.readToken("(");
               
                while (t.checkToken("("))
                {
                        t.readToken("(");
                       
                        float x = t.readNumber();
                        t.readToken(",");
                        float y = t.readNumber();
                       
                        offsetList.add(new CharacterOffset(x, y));
                       
                        t.readToken(")");
                       
                        if (!t.checkToken(","))
                                break;
                       
                        t.readToken(",");
                }              
               
                if (!t.checkToken(")"))
                        throw new ScanException("Syntax error in OffsetList!", t.getSurroundings());
               
                t.readToken(")");
               
                return offsetList;
        }
}