using Godot; using System.Collections.Generic; namespace Rokojori { [Tool] [GlobalClass] public partial class FontCreator:Node3D { [Export] public Font font; [Export] public string characterSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcedfghijklmnopqrstuvwxyz0123456789!?.-#+[]:,;_/"; [Export(PropertyHint.Dir)] public string exportPath; [Export] public FontDefinition fontDefinition; [Export] public Label3D label3D; [Export] public int elements = 3; [Export] public float offset = 0.1f; [Export] public Gradient fillGradient; [Export] public Gradient strokeGradient; [Export] public float height; [ExportToolButton( "Create Glyphs" )] public Callable createButton => Callable.From( ()=> CreateGlyphs() ) ; [Export] public Node3D[] glyphs; void CreateGlyphs() { this.DestroyChildren(); glyphs = []; var gList = new List(); for ( int i = 0; i < characterSet.Length; i++ ) { var g = CreateGlyph( characterSet[ i ] + "" ); gList.Add( g ); } glyphs = gList.ToArray(); ComputeWidths(); } async void ComputeWidths() { await this.RequestNextFrame(); await this.RequestNextFrame(); var glyphList = new List(); for ( int i = 0; i < glyphs.Length; i++ ) { var label = glyphs[ i ].Get(); var bounds = (label.GetAabb()); var scenePath = exportPath + "/scene " + glyphs[ i ].Name + ".tscn"; glyphs[ i ].SaveAs( scenePath, false ); var glyph = new FontGlyph(); glyph.glyphMesh = new SceneReference(); glyph.glyphMesh.scenePath = scenePath; glyph.width = bounds.Size.X; glyph.kerningGroup = 0; glyph.characters = characterSet[ i ] + ""; var glyphPath = exportPath + "/glyph " + glyphs[ i ].Name + ".tres"; glyph.SaveAs( glyphPath, false ); glyphList.Add( glyph ); } fontDefinition.glyphs = glyphList.ToArray(); await this.RequestNextFrame(); await this.RequestNextFrame(); EditorInterface.Singleton.GetResourceFilesystem().ScanSources(); } Node3D CreateGlyph( string character ) { var characterLabel = ""; for ( int i = 0; i < character.Length; i++ ) { if ( i != 0 ){ characterLabel += " "; } characterLabel += character[ i ].MapCharacterToName(); } var container = this.CreateChild( characterLabel ); for ( int i = 0; i < elements; i++ ) { var label = (Label3D)label3D.Duplicate(); label.Text = character; label.SetParent( container ); label.Name = characterLabel; label.SetLocalZ( i * offset ); label.Modulate = fillGradient.Sample( i / ( elements - 1f ) ); label.OutlineModulate = strokeGradient.Sample( i / ( elements - 1f ) ); } return container; } } }