Package com.badlogic.gdx.tools.bmfont

Source Code of com.badlogic.gdx.tools.bmfont.BitmapFontWriter$FontInfo

/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* 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 com.badlogic.gdx.tools.bmfont;


import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.PixmapIO;
import com.badlogic.gdx.graphics.g2d.BitmapFont.BitmapFontData;
import com.badlogic.gdx.graphics.g2d.BitmapFont.Glyph;
import com.badlogic.gdx.graphics.g2d.PixmapPacker.Page;
import com.badlogic.gdx.utils.Array;

/** A utility to output BitmapFontData to a FNT file. This can be useful for caching the result from TrueTypeFont, for faster load
* times.
*
* The font format is from the AngelCodeFont BMFont tool.
*
* @author mattdesl AKA davedes */
public class BitmapFontWriter {

  /** The output format. */
  public static enum OutputFormat {
   
    /** AngelCodeFont text format */
    Text,
    /** AngelCodeFont XML format */
    XML;
  }
 
  /** The output format */
  private static OutputFormat format = OutputFormat.Text;

  /** Sets the AngelCodeFont output format for subsequent writes; can be text (for LibGDX) or XML (for other engines, like
   * Pixi.js).
   *
   * @param fmt the output format to use */
  public static void setOutputFormat(OutputFormat fmt) {
    if (fmt==null)
      throw new NullPointerException("format cannot be null");
    format = fmt;
  }

  /** Returns the currently used output format.
   * @return the output format */
  public static OutputFormat getOutputFormat() {
    return format;
  }
 
  /** The Padding parameter for FontInfo. */
  public static class Padding {
    public int up, down, left, right;

    public Padding() {
    }
   
    public Padding(int up, int down, int left, int right) {
      this.up = up;
      this.down = down;
      this.left = left;
      this.right = right;
    }
  }

  /** The spacing parameter for FontInfo. */
  public static class Spacing {
    public int horizontal, vertical;
  }

  /** The font "info" line; this will be ignored by LibGDX's BitmapFont reader,
   * but useful for clean and organized output. */
  public static class FontInfo {
    /** Face name */
    public String face;
    /** Font size (pt) */
    public int size = 12;
    /** Whether the font is bold */
    public boolean bold;
    /** Whether the font is italic */
    public boolean italic;
    /** The charset; or null/empty for default */
    public String charset;
    /** Whether the font uses unicode glyphs */
    public boolean unicode = true;
    /** Stretch for height; default to 100% */
    public int stretchH = 100;
    /** Whether smoothing is applied */
    public boolean smooth = true;
    /** Amount of anti-aliasing that was applied to the font */
    public int aa = 2;
    /** Padding that was applied to the font */
    public Padding padding = new Padding();
    /** Horizontal/vertical spacing that was applied to font */
    public Spacing spacing = new Spacing();
    public int outline = 0;
   
    public FontInfo() {
    }
   
    public FontInfo(String face, int size) {
      this.face = face;
      this.size = size;
    }
  }
 
  private static String quote(Object params) {
    return quote(params, false);
  }
 
  private static String quote(Object params, boolean spaceAfter) {
    if (BitmapFontWriter.getOutputFormat() == OutputFormat.XML)
      return "\"" + params.toString().trim() + "\"" + (spaceAfter ? " " : "");
    else
      return params.toString();
  }

  /** Writes the given BitmapFontData to a file, using the specified <tt>pageRefs</tt> strings as the image paths for each texture
   * page. The glyphs in BitmapFontData have a "page" id, which references the index of the pageRef you specify here.
   *
   * The FontInfo parameter is useful for cleaner output; such as including a size and font face name hint. However, it can be
   * null to use default values. Ultimately, LibGDX ignores the "info" line when reading back fonts.
   *
   * Likewise, the scaleW and scaleH are only for cleaner output. They are currently ignored by LibGDX's reader. For maximum
   * compatibility with other BMFont tools, you should use the width and height of your texture pages (each page should be the
   * same size).
   *
   * @param fontData the bitmap font
   * @param pageRefs the references to each texture page image file, generally in the same folder as outFntFile
   * @param outFntFile the font file to save to (typically ends with '.fnt')
   * @param info the optional info for the file header; can be null
   * @param scaleW the width of your texture pages
   * @param scaleH the height of your texture pages */
  public static void writeFont (BitmapFontData fontData, String[] pageRefs, FileHandle outFntFile, FontInfo info, int scaleW, int scaleH) {
    if (info==null) {
      info = new FontInfo();
      info.face = outFntFile.nameWithoutExtension();
    }
   
    int lineHeight = (int)fontData.lineHeight;
    int pages = pageRefs.length;
    int packed = 0;
    int base = (int)((fontData.capHeight) + (fontData.flipped ? -fontData.ascent : fontData.ascent));
    OutputFormat fmt = BitmapFontWriter.getOutputFormat();
    boolean xml = fmt == OutputFormat.XML; 
   
    StringBuilder buf = new StringBuilder();
   
    if (xml) {
      buf.append("<font>\n");
    }
    String xmlOpen = xml ? "\t<" : "";
    String xmlCloseSelf = xml ? "/>" : "";
    String xmlTab = xml ? "\t" : "";
    String xmlClose = xml ? ">" : "";
   
    String xmlQuote = xml ? "\"" : "";
    String alphaChnlParams =
            xml ? " alphaChnl=\"0\" redChnl=\"0\" greenChnl=\"0\" blueChnl=\"0\""
               : " alphaChnl=0 redChnl=0 greenChnl=0 blueChnl=0";
    //INFO LINE
   
    buf.append(xmlOpen)
      .append("info face=\"")
      .append(info.face==null ? "" : info.face.replaceAll("\"", "'"))
      .append("\" size=").append( quote(info.size) )
      .append(" bold=").append( quote(info.bold ? 1 : 0) )
      .append(" italic=").append( quote(info.italic ? 1 : 0) )
      .append(" charset=\"").append(info.charset==null ? "" : info.charset)
      .append("\" unicode=").append( quote(info.unicode ? 1 : 0) )
      .append(" stretchH=").append( quote(info.stretchH) )
      .append(" smooth=").append( quote(info.smooth ? 1 : 0) )
      .append(" aa=").append( quote(info.aa) )
      .append(" padding=")
        .append(xmlQuote)
        .append(info.padding.up).append(",")
        .append(info.padding.down).append(",")
        .append(info.padding.left).append(",")
        .append(info.padding.right)
        .append(xmlQuote)
      .append(" spacing=")
        .append(xmlQuote)
        .append(info.spacing.horizontal).append(",")
        .append(info.spacing.vertical)
        .append(xmlQuote)
      .append(xmlCloseSelf)
      .append("\n");
   
    //COMMON line
    buf.append(xmlOpen)
      .append("common lineHeight=").append( quote(lineHeight) )
      .append(" base=").append( quote(base) )
      .append(" scaleW=").append( quote(scaleW) )
      .append(" scaleH=").append( quote(scaleH) )
      .append(" pages=").append( quote(pages) )
      .append(" packed=").append( quote(packed) )
      .append(alphaChnlParams)
      .append(xmlCloseSelf)
      .append("\n");
   
    if (xml)
      buf.append("\t<pages>\n");
   
    //PAGES
    for (int i=0; i<pageRefs.length; i++) {
      buf.append(xmlTab)
        .append(xmlOpen)
        .append("page id=")
        .append( quote(i) )
        .append(" file=\"")
        .append(pageRefs[i])
        .append("\"")
        .append(xmlCloseSelf)
        .append("\n");
    }
   
    if (xml)
      buf.append("\t</pages>\n");
   
    //CHARS
    Array<Glyph> glyphs = new Array<Glyph>(256);
    for (int i=0; i<fontData.glyphs.length; i++) {
      if (fontData.glyphs[i]==null)
        continue;
     
      for (int j=0; j<fontData.glyphs[i].length; j++) {
        if (fontData.glyphs[i][j]!=null) {
          glyphs.add(fontData.glyphs[i][j]);
        }
      }
    }
   
    buf.append(xmlOpen)
      .append("chars count=").append(quote(glyphs.size))
      .append(xmlClose)
      .append("\n");
   
    //CHAR definitions
    for (int i=0; i<glyphs.size; i++) {
      Glyph g = glyphs.get(i);
      buf.append(xmlTab)
        .append(xmlOpen)
        .append("char id=")
        .append(quote( String.format("%-5s", g.id), true ))
        .append("x=").append(quote( String.format("%-5s", g.srcX), true ) )
        .append("y=").append(quote( String.format("%-5s", g.srcY), true ) )
        .append("width=").append(quote( String.format("%-5s", g.width), true ) )
        .append("height=").append(quote( String.format("%-5s", g.height), true ) )
        .append("xoffset=").append(quote( String.format("%-5s", g.xoffset), true ) )
        .append("yoffset=").append(quote( String.format("%-5s", fontData.flipped ? g.yoffset : -(g.height + g.yoffset) ), true ) )
        .append("xadvance=").append(quote( String.format("%-5s", g.xadvance), true ) )
        .append("page=").append(quote( String.format("%-5s", g.page), true ) )
        .append("chnl=").append(quote(0, true))
        .append(xmlCloseSelf)
        .append("\n");
    }
   
    if (xml)
      buf.append("\t</chars>\n");
   
    //KERNINGS
    int kernCount = 0;
    StringBuilder kernBuf = new StringBuilder();
    for (int i = 0; i < glyphs.size; i++) {
      for (int j = 0; j < glyphs.size; j++) {
        Glyph first = glyphs.get(i);
        Glyph second = glyphs.get(j);
        int kern = first.getKerning((char)second.id);
        if (kern!=0) {
          kernCount++;
          kernBuf.append(xmlTab)
              .append(xmlOpen)
              .append("kerning first=").append(quote(first.id))
              .append(" second=").append(quote(second.id))
              .append(" amount=").append(quote(kern, true))
              .append(xmlCloseSelf)
              .append("\n");
        }
      }
    }

    //KERN info
    buf.append(xmlOpen)
      .append("kernings count=").append(quote(kernCount))
      .append(xmlClose)
      .append("\n");
    buf.append(kernBuf);
   
    if (xml) {
      buf.append("\t</kernings>\n");
      buf.append("</font>");
    }
   
    String charset = info.charset;
    if (charset!=null&&charset.length()==0)
      charset = null;
   
    outFntFile.writeString(buf.toString(), false, charset);
  }

 
  /** A utility method which writes the given font data to a file.
   *
   * The specified pixmaps are written to the parent directory of <tt>outFntFile</tt>, using that file's name without an
   * extension for the PNG file name(s).
   *
   * The specified FontInfo is optional, and can be null.
   *
   * Typical usage looks like this:
   *
   * <pre>
   * BitmapFontWriter.writeFont(myFontData, myFontPixmaps, Gdx.files.external(&quot;fonts/output.fnt&quot;), new FontInfo(&quot;Arial&quot;, 16));
   * </pre>
   *
   * @param fontData the font data
   * @param pages the pixmaps to write as PNGs
   * @param outFntFile the output file for the font definition
   * @param info the optional font info for the header file, can be null */
  public static void writeFont (BitmapFontData fontData, Pixmap[] pages, FileHandle outFntFile, FontInfo info) {
    String[] pageRefs = writePixmaps(pages, outFntFile.parent(), outFntFile.nameWithoutExtension());
   
    //write the font data
    writeFont(fontData, pageRefs, outFntFile, info, pages[0].getWidth(), pages[0].getHeight());
  }

  /** A utility method to write the given array of pixmaps to the given output directory, with the specified file name. If the
   * pages array is of length 1, then the resulting file ref will look like: "fileName.png".
   *
   * If the pages array is greater than length 1, the resulting file refs will be appended with "_N", such as "fileName_0.png",
   * "fileName_1.png", "fileName_2.png" etc.
   *
   * The returned string array can then be passed to the <tt>writeFont</tt> method.
   *
   * Note: None of the pixmaps will be disposed.
   *
   * @param pages the pages of pixmap data to write
   * @param outputDir the output directory
   * @param fileName the file names for the output images
   * @return the array of string references to be used with <tt>writeFont</tt> */
  public static String[] writePixmaps (Pixmap[] pages, FileHandle outputDir, String fileName) {
    if (pages==null || pages.length==0)
      throw new IllegalArgumentException("no pixmaps supplied to BitmapFontWriter.write");
   
    String[] pageRefs = new String[pages.length];
   
    for (int i=0; i<pages.length; i++) {
      String ref = pages.length==1 ? (fileName+".png") : (fileName+"_"+i+".png");
     
      //the ref for this image
      pageRefs[i] = ref;
     
      //write the PNG in that directory
      PixmapIO.writePNG(outputDir.child(ref), pages[i]);
    }
    return pageRefs;
  }

  /** A convenience method to write pixmaps by page; typically returned from a PixmapPacker when used alongside
   * FreeTypeFontGenerator.
   *
   * @param pages the pages containing the Pixmaps
   * @param outputDir the output directory
   * @param fileName the file name
   * @return the file refs */
  public static String[] writePixmaps (Array<Page> pages, FileHandle outputDir, String fileName) {
    Pixmap[] pix = new Pixmap[pages.size];
    for (int i=0; i<pages.size; i++) {
      pix[i] = pages.get(i).getPixmap();
    }
    return writePixmaps(pix, outputDir, fileName);
  }
}
TOP

Related Classes of com.badlogic.gdx.tools.bmfont.BitmapFontWriter$FontInfo

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.