miduo_client/Assets/Scripts/Editor/UGUIFontEditor/FontMakerWizard.cs

230 lines
8.1 KiB
C#

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using System.IO;
using System.Xml;
using System.Text;
public class FontMakerWizard : ScriptableWizard
{
public TextAsset xmlFile;
public int leftPadding;
public int rightPadding;
public int topPadding;
public int bottomPadding;
public int advanceOffset;
class Glyph
{
public char code;
public Rect bound;
public Rect interiorBound;
public int baseline;
public int spacingA;
public int spacingB;
public int spacingC;
}
private int lineHeight;
private int baseline;
private int textureWidth;
private int textureHeight;
private int glyphWidth;
private int glyphHeight;
private string texturePath;
private List<Glyph> glyphList;
[MenuItem("Tools/Font/Convert FontMaker")]
static void CreateWindow()
{
ScriptableWizard.DisplayWizard<FontMakerWizard>("Convert FontMaker Config File", "Convert");
}
void OnWizardUpdate()
{
helpString = "Specify font config file";
isValid = (xmlFile != null);
}
void OnWizardCreate()
{
LoadGlyph();
ExportBMFont();
}
void ExportBMFont()
{
StringBuilder sb = new StringBuilder();
// common lineHeight=64 base=51 scaleW=512 scaleH=512 pages=1
sb.AppendFormat("common lineHeight={0} base={1} scaleW={2} scaleH={3} pages=1", lineHeight, baseline, textureWidth, textureHeight);
sb.AppendLine();
// page id=0 file="textureName.png"
string path = Path.GetFileName(texturePath);
sb.AppendFormat("page id=0 file=\"{0}\"", path);
sb.AppendLine();
// char id=13 x=506 y=62 width=3 height=3 xoffset=-1 yoffset=50 xadvance=0 page=0 chnl=15
foreach (var glyph in glyphList)
{
int x = (int)(glyph.bound.x + glyph.interiorBound.x) - leftPadding;
int y = (int)(glyph.bound.y + glyph.interiorBound.y) - topPadding;
int w = (int)glyph.interiorBound.width + (rightPadding + leftPadding);
int h = (int)glyph.interiorBound.height + (topPadding + bottomPadding);
int xOffset = glyph.spacingA;
int yOffset = (int)glyph.interiorBound.y - topPadding;
int xAdvance = glyph.spacingA + glyph.spacingB + glyph.spacingC + advanceOffset;
sb.AppendFormat("char id={0} x={1} y={2} width={3} height={4} xoffset={5} yoffset={6} xadvance={7} page=0 chnl=15",
(int)glyph.code, x, y, w, h, xOffset, yOffset, xAdvance);
sb.AppendLine();
}
string xmlPath = AssetDatabase.GetAssetPath(xmlFile);
string outputDirectory = Path.GetDirectoryName(xmlPath) + "/" + Path.GetDirectoryName(texturePath);
string fntPath = outputDirectory + "/" + Path.GetFileNameWithoutExtension(xmlPath) + ".fnt";
Debug.Log("Write fnt file " + fntPath);
// save fnt file
File.WriteAllText(fntPath, sb.ToString(), Encoding.UTF8);
// refresh database
AssetDatabase.Refresh();
}
void LoadGlyph()
{
glyphList = new List<Glyph>();
// load font config file
using (Stream stream = new MemoryStream(xmlFile.bytes))
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = true;
settings.IgnoreWhitespace = true;
using (XmlReader reader = XmlReader.Create(stream, settings))
{
reader.MoveToContent();
reader.ReadStartElement("fontconfig");
{
// typeface
if (reader.Name == "font")
{
lineHeight = int.Parse(reader.GetAttribute("height"));
// move to next
reader.Read();
}
// texture info
if (reader.Name == "texture")
{
textureWidth = int.Parse(reader.GetAttribute("width"));
textureHeight = int.Parse(reader.GetAttribute("height"));
// move to next
reader.Read();
}
// texture info
reader.ReadToFollowing("size");
if (reader.Name == "size")
{
glyphWidth = int.Parse(reader.GetAttribute("width"));
glyphHeight = int.Parse(reader.GetAttribute("height"));
// move to next
reader.Read();
}
// images
reader.ReadToFollowing("images");
if (!reader.IsEmptyElement)
{
List<string> images = new List<string>();
reader.ReadStartElement("images");
if (reader.Name == "image")
{
do
{
string imagePath = reader.GetAttribute("path");
images.Add(imagePath);
}
while (reader.ReadToNextSibling("image"));
}
reader.ReadEndElement();
if (images.Count > 0)
{
// only handle one texture
texturePath = images[0];
}
else
{
Debug.LogError("image path missing");
return;
}
}
else
{
reader.Read();
}
// glyph
if (!reader.IsEmptyElement)
{
reader.ReadStartElement("glyphs");
if (reader.Name == "glyph")
{
do
{
char character = char.Parse(reader.GetAttribute("char"));
int pageIndex = int.Parse(reader.GetAttribute("page"));
int x = int.Parse(reader.GetAttribute("x"));
int y = int.Parse(reader.GetAttribute("y"));
int w = int.Parse(reader.GetAttribute("w"));
int h = int.Parse(reader.GetAttribute("h"));
int ix = int.Parse(reader.GetAttribute("ix"));
int iy = int.Parse(reader.GetAttribute("iy"));
int iw = int.Parse(reader.GetAttribute("iw"));
int ih = int.Parse(reader.GetAttribute("ih"));
Glyph glyph = new Glyph();
glyph.code = character;
glyph.bound = new Rect(x, y, w, h);
glyph.interiorBound = new Rect(ix, iy, iw, ih);
glyph.baseline = int.Parse(reader.GetAttribute("baseline"));
glyph.spacingA = int.Parse(reader.GetAttribute("spacingA"));
glyph.spacingB = int.Parse(reader.GetAttribute("spacingB"));
glyph.spacingC = int.Parse(reader.GetAttribute("spacingC"));
baseline = glyph.baseline;
glyphList.Add(glyph);
}
while (reader.ReadToNextSibling("glyph"));
}
reader.ReadEndElement();
}
else
{
reader.Read();
}
}
reader.ReadEndElement();
}
}
}
}