132 lines
2.5 KiB
C#
132 lines
2.5 KiB
C#
![]() |
|
||
|
using Godot;
|
||
|
using System.Collections.Generic;
|
||
|
|
||
|
namespace Rokojori
|
||
|
{
|
||
|
public class FontFXGroup
|
||
|
{
|
||
|
public FontDefinition fontDefinition;
|
||
|
public float scale = 1;
|
||
|
public string characters;
|
||
|
|
||
|
float _width = 0;
|
||
|
public float width
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
|
||
|
if ( _width == 0 )
|
||
|
{
|
||
|
_width = fontDefinition.GetWidth( characters ) * scale;
|
||
|
}
|
||
|
|
||
|
return _width;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public List<float> relativeOffsets => fontDefinition.GetOffsets( characters ).Map( o => o * scale );
|
||
|
|
||
|
public List<float> absoluteOffsets;
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
public class FontFXLine
|
||
|
{
|
||
|
public List<FontFXGroup> groups = new List<FontFXGroup>();
|
||
|
|
||
|
public void ComptuteOffsets()
|
||
|
{
|
||
|
var offset = 0f;
|
||
|
|
||
|
for ( int i = 0; i < groups.Count; i++ )
|
||
|
{
|
||
|
var width = groups[ i ].width;
|
||
|
groups[ i ].absoluteOffsets = groups[ i ].relativeOffsets.Map( o => o + offset );
|
||
|
offset += width;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public List<FontFXLine> LayoutLineWrapped( float width )
|
||
|
{
|
||
|
var lines = new List<FontFXLine>();
|
||
|
var line = new FontFXLine();
|
||
|
|
||
|
var lineWidth = 0f;
|
||
|
|
||
|
groups.ForEach(
|
||
|
( g )=>
|
||
|
{
|
||
|
var groupWidth = g.width;
|
||
|
var nextEnd = lineWidth + groupWidth;
|
||
|
|
||
|
if ( nextEnd > width )
|
||
|
{
|
||
|
lines.Add( line );
|
||
|
line = new FontFXLine();
|
||
|
lineWidth = 0;
|
||
|
}
|
||
|
|
||
|
line.groups.Add( g );
|
||
|
lineWidth += groupWidth;
|
||
|
}
|
||
|
);
|
||
|
|
||
|
lines.Add( line );
|
||
|
|
||
|
return lines;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
public class FontFXLayouter
|
||
|
{
|
||
|
|
||
|
public List<FontFXLine> Layout( string text, FontDefinition font, float maxWidth = 10000000 )
|
||
|
{
|
||
|
var lines = new List<FontFXLine>();
|
||
|
|
||
|
var lexed = WordLexer.Lex( text );
|
||
|
|
||
|
if ( lexed == null )
|
||
|
{
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
var line = new FontFXLine();
|
||
|
|
||
|
lexed.ForEach(
|
||
|
( l )=>
|
||
|
{
|
||
|
if ( l.isDone )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( l.Is( WordLexer.LineBreak ) )
|
||
|
{
|
||
|
lines.Add( line );
|
||
|
|
||
|
line = new FontFXLine();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var group = new FontFXGroup();
|
||
|
group.fontDefinition = font;
|
||
|
group.characters = l.match;
|
||
|
|
||
|
line.groups.Add( group );
|
||
|
}
|
||
|
);
|
||
|
|
||
|
lines.Add( line );
|
||
|
|
||
|
|
||
|
lines = lines.MultiMap( ( line, index ) => line.LayoutLineWrapped( maxWidth ) );
|
||
|
|
||
|
|
||
|
return lines;
|
||
|
}
|
||
|
}
|
||
|
}
|