using System.Collections.Generic;
using UnityEngine;
namespace FairyGUI
{
///
///
///
public class BitmapFont : BaseFont
{
///
///
///
public class BMGlyph
{
public float x;
public float y;
public float width;
public float height;
public int advance;
public int lineHeight;
public Vector2[] uv = new Vector2[4];
public int channel;//0-n/a, 1-r,2-g,3-b,4-alpha
}
///
///
///
public int size;
///
///
///
public bool resizable;
///
/// Font generated by BMFont use channels.
///
public bool hasChannel;
protected Dictionary _dict;
protected BMGlyph _glyph;
float _scale;
public BitmapFont()
{
this.canTint = true;
this.hasChannel = false;
this.customOutline = true;
this.shader = ShaderConfig.bmFontShader;
_dict = new Dictionary();
_scale = 1;
}
public void AddChar(char ch, BMGlyph glyph)
{
_dict[ch] = glyph;
}
override public void SetFormat(TextFormat format, float fontSizeScale)
{
if (resizable)
_scale = (float)format.size / size * fontSizeScale;
else
_scale = fontSizeScale;
if (canTint)
format.FillVertexColors(vertexColors);
}
override public bool GetGlyph(char ch, out float width, out float height, out float baseline)
{
if (ch == ' ')
{
width = Mathf.RoundToInt(size * _scale / 2);
height = Mathf.RoundToInt(size * _scale);
baseline = height;
_glyph = null;
return true;
}
else if (_dict.TryGetValue((int)ch, out _glyph))
{
width = Mathf.RoundToInt(_glyph.advance * _scale);
height = Mathf.RoundToInt(_glyph.lineHeight * _scale);
baseline = height;
return true;
}
else
{
width = 0;
height = 0;
baseline = 0;
return false;
}
}
static Vector3 bottomLeft;
static Vector3 topLeft;
static Vector3 topRight;
static Vector3 bottomRight;
static Color32[] vertexColors = new Color32[4];
override public void DrawGlyph(VertexBuffer vb, float x, float y)
{
if (_glyph == null) //space
return;
topLeft.x = x + _glyph.x * _scale;
topLeft.y = y + (_glyph.lineHeight - _glyph.y) * _scale;
bottomRight.x = x + (_glyph.x + _glyph.width) * _scale;
bottomRight.y = topLeft.y - _glyph.height * _scale;
topRight.x = bottomRight.x;
topRight.y = topLeft.y;
bottomLeft.x = topLeft.x;
bottomLeft.y = bottomRight.y;
vb.vertices.Add(bottomLeft);
vb.vertices.Add(topLeft);
vb.vertices.Add(topRight);
vb.vertices.Add(bottomRight);
vb.uvs.AddRange(_glyph.uv);
if (hasChannel)
{
Vector2 channel = new Vector2(_glyph.channel, 0);
vb.uvs2.Add(channel);
vb.uvs2.Add(channel);
vb.uvs2.Add(channel);
vb.uvs2.Add(channel);
}
if (canTint)
{
vb.colors.Add(vertexColors[0]);
vb.colors.Add(vertexColors[1]);
vb.colors.Add(vertexColors[2]);
vb.colors.Add(vertexColors[3]);
}
else
{
vb.colors.Add(Color.white);
vb.colors.Add(Color.white);
vb.colors.Add(Color.white);
vb.colors.Add(Color.white);
}
}
override public bool HasCharacter(char ch)
{
return ch == ' ' || _dict.ContainsKey((int)ch);
}
override public int GetLineHeight(int size)
{
if (_dict.Count > 0)
{
using (var et = _dict.GetEnumerator())
{
et.MoveNext();
if (resizable)
return Mathf.RoundToInt((float)et.Current.Value.lineHeight * size / this.size);
else
return et.Current.Value.lineHeight;
}
}
else
return 0;
}
}
}