IndieGame/client/Assets/Plugins/zbitmap/zbitmapfont_TMP/Editor/BitmapFont2TMPro.cs
2024-10-22 17:38:59 +08:00

223 lines
8.3 KiB
C#

using UnityEngine;
using UnityEditor;
using UnityEngine.TextCore;
using TMPro;
using zbitmapfont;
using UnityEngine.TextCore.LowLevel;
using System.Drawing;
using System.Runtime.InteropServices;
using zbitmapfont;
namespace zbitmapfont
{
public static class BitmapFont2TMPro
{
static void PatchGlyph(RawCharacterInfo character, int textureHeight, int textureWidth, ref Glyph g)
{
var scaleH = textureWidth / textureHeight > 1 ? textureWidth / textureHeight : 1;
var scaleW = textureHeight / textureWidth > 1 ? textureHeight / textureWidth : 1;
g.glyphRect = new GlyphRect(
character.X * scaleW,
(textureHeight - character.Y - character.Height) * scaleH,
character.Width * scaleW,
character.Height * scaleH
);
g.metrics = new GlyphMetrics(
character.Width,
character.Height,
character.Xoffset,
-character.Yoffset,
character.Xadvance
);
}
[MenuItem("Assets/zbitmapfont/CreateTMP_FontAsset")]
public static void CreateTMP_FontAsset()
{
foreach (var a in Selection.assetGUIDs)
{
var p = AssetDatabase.GUIDToAssetPath(a);
if (System.IO.Directory.Exists(p))
{
string destPath = p;
if (!BitmapFontTool.CreateBitmapFont(p, destPath))
{
throw new System.Exception("CreateBitmapFont failed: " + p);
}
p += ".fnt";
}
if (!p.EndsWith(".fnt"))
{
continue;
}
if (!System.IO.File.Exists(p))
{
continue;
}
Create(p);
}
}
static void Create(string fntFilePath)
{
var pngPath = System.IO.Path.GetDirectoryName(fntFilePath) + "/" + System.IO.Path.GetFileNameWithoutExtension(fntFilePath) + "_0.png";
Texture2D m_FontAtlasTexture = AssetDatabase.LoadAssetAtPath<Texture2D>(pngPath);
var assetPath = System.IO.Path.GetDirectoryName(fntFilePath) + "/" + System.IO.Path.GetFileNameWithoutExtension(fntFilePath) + ".asset";
var tex_FileName = System.IO.Path.GetFileNameWithoutExtension(assetPath);
//Debug.Log("Creating TextMeshPro font asset!");
var fontAsset = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(assetPath);
if (fontAsset == null)
{
fontAsset = ScriptableObject.CreateInstance<TMP_FontAsset>(); // Create new TextMeshPro Font Asset.
AssetDatabase.CreateAsset(fontAsset, assetPath);
}
// Set version number of font asset
//fontAsset.version = "1.1.0";
//Set Font Asset Type
//fontAsset.atlasRenderMode = GlyphRenderMode.RASTER;
// Reference to the source font file GUID.
//fontAsset.m_SourceFontFile_EditorRef = m_DestinationFontFile.sourceFontFile;
//fontAsset.m_SourceFontFileGUID = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_DestinationFontFile.sourceFontFile));
// Add FaceInfo to Font Asset
//fontAsset.faceInfo = m_FaceInfo;
//// Add GlyphInfo[] to Font Asset
//fontAsset.glyphTable = m_FontGlyphTable;
//// Add CharacterTable[] to font asset.
//fontAsset.characterTable = m_FontCharacterTable;
//// Sort glyph and character tables.
//fontAsset.SortAllTables();
//// Get and Add Kerning Pairs to Font Asset
//if (m_IncludeFontFeatures)
// fontAsset.fontFeatureTable = GetKerningTable();
// Add Font Atlas as Sub-Asset
fontAsset.atlasTextures = new Texture2D[] { m_FontAtlasTexture };
//fontAsset.atlasWidth = m_FontAtlasTexture.width;
//fontAsset.atlasHeight = m_FontAtlasTexture.height;
//fontAsset.atlasPadding = m_Padding;
//AssetDatabase.AddObjectToAsset(m_FontAtlasTexture, fontAsset);
// Create new Material and Add it as Sub-Asset
Shader default_Shader = Shader.Find("TextMeshPro/Bitmap Custom Atlas"); // m_shaderSelection;
Material tmp_material = AssetDatabase.LoadAssetAtPath<Material>(assetPath);
if (tmp_material == null)
{
tmp_material = new Material(default_Shader);
tmp_material.name = tex_FileName + " Material";
fontAsset.material = tmp_material;
AssetDatabase.AddObjectToAsset(tmp_material, fontAsset);
}
tmp_material.SetTexture(ShaderUtilities.ID_MainTex, m_FontAtlasTexture);
fontAsset.GetType().GetProperty("version").SetValue(fontAsset, "1.1.0");
fontAsset.GetType().GetProperty("atlasRenderMode").SetValue(fontAsset, (int)GlyphRenderMode.RASTER);
//fontAsset.GetType().GetProperty("faceInfo").SetValue(fontAsset, m_DestinationFontFile.faceInfo);
fontAsset.GetType().GetProperty("atlasWidth").SetValue(fontAsset, m_FontAtlasTexture.width);
fontAsset.GetType().GetProperty("atlasHeight").SetValue(fontAsset, m_FontAtlasTexture.height);
fontAsset.GetType().GetProperty("atlasPadding").SetValue(fontAsset, 1);
//fontAsset.GetType().GetField("m_SourceFontFile_EditorRef", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(fontAsset, m_DestinationFontFile.sourceFontFile);
//fontAsset.GetType().GetField("m_SourceFontFileGUID", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).SetValue(fontAsset, AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(m_DestinationFontFile.sourceFontFile)));
var fontFile = fontAsset;
var fnt = FntParse.GetFntParse(System.IO.File.ReadAllText(fntFilePath));
fontFile.characterTable.Clear();
//fontFile.characterLookupTable.Clear();
fontFile.glyphTable.Clear();
//fontFile.glyphLookupTable.Clear();
for (uint j = 0; j < fnt.charInfos.Length; j++)
{
var c = fnt.charInfos[j];
var a = new TMP_Character();
a.unicode = (uint)c.index;
a.glyphIndex = j;
a.textAsset = fontFile;
var glyph = new Glyph();
PatchGlyph(fnt.rawCharInfos[j],
fnt.textureHeight,
fnt.textureWidth,
ref glyph);
glyph.index = j;
glyph.atlasIndex = 0;
a.glyph = glyph;
fontFile.characterTable.Add(a);
//fontFile.characterLookupTable.Add(a.unicode, a);
fontFile.glyphTable.Add(glyph);
//fontFile.glyphLookupTable.Add(j, glyph);
}
fontAsset.GetType().GetMethod("SortAllTables", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).Invoke(fontAsset, null);
var maxHeight = 0;
for (int j = 0; j < fnt.charInfos.Length; j++)
{
maxHeight = Mathf.Max(maxHeight, Mathf.Abs(fnt.charInfos[j].minY - fnt.charInfos[j].maxY));
}
var newFaceInfo = fontFile.faceInfo;
//newFaceInfo.baseline = fnt.lineBaseHeight;
//newFaceInfo.lineHeight = fnt.lineHeight;
//newFaceInfo.ascentLine = fnt.lineHeight;
newFaceInfo.baseline = 0;
newFaceInfo.lineHeight = maxHeight;
newFaceInfo.ascentLine = 0;
newFaceInfo.pointSize = fnt.fontSize;
newFaceInfo.descentLine = -maxHeight;
var fontType = typeof(TMP_FontAsset);
var faceInfoProperty = fontType.GetProperty("faceInfo");
faceInfoProperty.SetValue(fontFile, newFaceInfo);
AssetDatabase.Refresh();
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
AssetDatabase.SaveAssets();
}
}
}