Package org.terasology.rendering.assets.font

Source Code of org.terasology.rendering.assets.font.FontLoader

/*
* Copyright 2013 MovingBlocks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.terasology.rendering.assets.font;

import com.google.common.base.Charsets;
import org.terasology.asset.AssetLoader;
import org.terasology.asset.AssetType;
import org.terasology.asset.AssetUri;
import org.terasology.asset.Assets;
import org.terasology.module.Module;
import org.terasology.naming.Name;
import org.terasology.rendering.assets.material.Material;
import org.terasology.rendering.assets.material.MaterialData;
import org.terasology.rendering.assets.texture.Texture;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* @author Immortius
*/
public class FontLoader implements AssetLoader<FontData> {

    private static final String INTEGER_PATTERN = "((?:[\\+-]?\\d+)(?:[eE][\\+-]?\\d+)?)";

    // Common patterns
    private Pattern lineHeightPattern = Pattern.compile("lineHeight=" + INTEGER_PATTERN);
    private Pattern pagesPattern = Pattern.compile("pages=" + INTEGER_PATTERN);

    private Pattern pagePattern = Pattern.compile("page id=" + INTEGER_PATTERN + " file=\"(.*)\"");
    private Pattern charsPattern = Pattern.compile("chars count=" + INTEGER_PATTERN);
    private Pattern charPattern = Pattern.compile("char\\s+" +
            "id=" + INTEGER_PATTERN + "\\s+" +
            "x=" + INTEGER_PATTERN + "\\s+" +
            "y=" + INTEGER_PATTERN + "\\s+" +
            "width=" + INTEGER_PATTERN + "\\s+" +
            "height=" + INTEGER_PATTERN + "\\s+" +
            "xoffset=" + INTEGER_PATTERN + "\\s+" +
            "yoffset=" + INTEGER_PATTERN + "\\s+" +
            "xadvance=" + INTEGER_PATTERN + "\\s+" +
            "page=" + INTEGER_PATTERN + "\\s+" +
            "chnl=" + INTEGER_PATTERN + "\\s*");

    @Override
    public FontData load(Module module, InputStream stream, List<URL> urls, List<URL> deltas) throws IOException {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream, Charsets.UTF_8))) {
            FontDataBuilder builder = new FontDataBuilder();
            parseHeader(reader.readLine());
            int numPages = parseCommon(builder, reader.readLine());

            for (int i = 0; i < numPages; ++i) {
                parsePage(builder, module.getId(), reader.readLine());
            }

            int charCount = getCharacterCount(reader.readLine());
            for (int i = 0; i < charCount; ++i) {
                parseCharacter(builder, reader.readLine());
            }

            return builder.build();
        }
    }

    private void parseCharacter(FontDataBuilder builder, String charInfo) throws IOException {
        Matcher matcher = charPattern.matcher(charInfo);
        if (matcher.matches()) {
            try {
                builder.startCharacter(Integer.parseInt(matcher.group(1)))
                        .setCharacterX(Integer.parseInt(matcher.group(2)))
                        .setCharacterY(Integer.parseInt(matcher.group(3)))
                        .setCharacterWidth(Integer.parseInt(matcher.group(4)))
                        .setCharacterHeight(Integer.parseInt(matcher.group(5)))
                        .setCharacterXOffset(Integer.parseInt(matcher.group(6)))
                        .setCharacterYOffset(Integer.parseInt(matcher.group(7)))
                        .setCharacterXAdvance(Integer.parseInt(matcher.group(8)))
                        .setCharacterPage(Integer.parseInt(matcher.group(9)))
                        .endCharacter();
            } catch (IllegalArgumentException e) {
                throw new IOException("Failed to load font", e);
            }
        } else {
            throw new IOException("Failed to parse font - invalid char line '" + charInfo + "'");
        }
    }

    private int getCharacterCount(String charsInfo) throws IOException {
        Matcher charsMatcher = charsPattern.matcher(charsInfo);
        if (charsMatcher.matches()) {
            return Integer.parseInt(charsMatcher.group(1));
        } else {
            throw new IOException("Failed to load font - invalid chars line '" + charsInfo + "'");
        }
    }

    private void parsePage(FontDataBuilder builder, Name moduleName, String pageInfo) throws IOException {
        Matcher pageMatcher = pagePattern.matcher(pageInfo);
        if (pageMatcher.matches()) {
            int pageId = Integer.parseInt(pageMatcher.group(1));
            String textureName = pageMatcher.group(2).substring(0, pageMatcher.group(2).lastIndexOf('.'));
            Texture texture = Assets.getTexture(moduleName, textureName);
            if (texture == null) {
                throw new IOException("Failed to load font - unable to resolve font page '" + textureName + "'");
            }

            MaterialData materialData = new MaterialData(Assets.getShader("engine:font"));
            materialData.setParam("texture", texture);
            AssetUri matName = new AssetUri(AssetType.MATERIAL, moduleName, textureName + "_font");
            Material pageMat = Assets.generateAsset(matName, materialData, Material.class);

            builder.addPage(pageId, texture, pageMat);
        } else {
            throw new IOException("Failed to load font - invalid page line '" + pageInfo + "'");
        }
    }


    private void parseHeader(String info) throws IOException {
        if (!info.startsWith("info ")) {
            throw new IOException("Invalid font - missing info line");
        }
        // We don't actually use anything from the info line
    }

    private int parseCommon(FontDataBuilder builder, String commonLine) throws IOException {
        if (!commonLine.startsWith("common ")) {
            throw new IOException("Failed to load font - missing common line");
        }
        builder.setLineHeight(findInteger(lineHeightPattern, commonLine));
        return findInteger(pagesPattern, commonLine);
    }

    private int findInteger(Pattern pattern, String in) {
        Matcher matcher = pattern.matcher(in);
        if (matcher.find()) {
            return Integer.parseInt(matcher.group(1));
        }
        return 0;
    }

}
TOP

Related Classes of org.terasology.rendering.assets.font.FontLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.