rj-action-library/Runtime/Rendering/FontFX/FontFX.cs

116 lines
2.4 KiB
C#
Raw Normal View History

2025-08-31 06:05:39 +00:00
using Godot;
using System.Collections.Generic;
namespace Rokojori
{
[Tool]
[GlobalClass]
public partial class FontFX:Node3D
{
[ExportToolButton( "Update")]
public Callable updateButton => Callable.From( ()=>{ _Update(); } );
[ExportToolButton( "Clear Cache")]
public Callable clearCacheButton => Callable.From( ()=>{ ClearCache(); } );
[Export]
public FontDefinition font
{
get => _font;
set
{
_font = value;
_Update();
}
}
FontDefinition _font;
[Export]
public LocaleText text{ get => _text; set{ _text = value; _Update(); } }
LocaleText _text;
FontFXLayouter _layouter = new FontFXLayouter();
Transformable<FontGlyph> _layout;
Dictionary<string,PackedScene> _glyphMap = new Dictionary<string, PackedScene>();
void ClearCache()
{
_glyphMap = new Dictionary<string, PackedScene>();
}
PackedScene GetGlyph( string character )
{
if ( _glyphMap.ContainsKey( character ) )
{
return _glyphMap[ character ];
}
var g = font.GetFontGlyph( character );
_glyphMap[ character ] = g == null ? null : g.glyphMesh.LoadScene();
return _glyphMap[ character ];
}
void _Update()
{
if ( _font == null || _text == null )
{
return;
}
this.DestroyChildren();
var realText = _text.currentValue;
var lines = _layouter.Layout( realText, _font );
var offset = 0f;
lines.ForEach(
( line )=>
{
offset = CreateLine( line, offset );
}
);
}
float CreateLine( FontFXLine line, float offset )
{
line.ComptuteOffsets();
line.groups.ForEach(
( g )=>
{
CreateGroup( g, offset );
}
);
return offset + font.baseToBottom + font.baseToTop;
}
void CreateGroup( FontFXGroup group, float offset )
{
for ( int i = 0; i < group.characters.Length; i++ )
{
var sc = GetGlyph( group.characters[ i ] + "" );
if ( sc == null )
{
continue;
}
var n = sc.Instantiate<Node3D>();
n.Name = this.GetChildCount() + "-" + group.characters[ i ].MapCharacterToName();
n.SetParent( this );
n.SetLocalX( group.absoluteOffsets[ i ] );
n.SetLocalY( -offset );
}
}
}
}