Simple bidirectional text

This commit is contained in:
Simon Lübeß
2022-01-08 02:17:35 +01:00
parent e292029015
commit 78faf4cb81
4 changed files with 89 additions and 35 deletions
+78 -27
View File
@@ -107,7 +107,15 @@ namespace GlitchyEngine.Renderer.Text
} }
} }
public static PreparedText PrepareText(Font font, String text, float fontSize, Color fontColor = .White, Color bitmapColor = .White, float lineSpaceScale = 1.0f) public enum TextDirection
{
case LeftToRight;
case RightToLeft;
case TopToBottom;
case BottomToTop;
}
public static PreparedText PrepareText(Font font, String text, float fontSize, Color fontColor = .White, Color bitmapColor = .White, float lineSpaceScale = 1.0f, TextDirection direction = .LeftToRight)
{ {
if(text.IsWhiteSpace) if(text.IsWhiteSpace)
return .Empty; return .Empty;
@@ -132,8 +140,20 @@ namespace GlitchyEngine.Renderer.Text
//PreparedLine currentLine = new PreparedLine(); //PreparedLine currentLine = new PreparedLine();
void FlushShapeBuffer(Font font, float scale) // Stack to keep track of the text direction.
List<TextDirection> textDirectionStack = scope .();
textDirectionStack.Add(direction);
int movedLines = 0;
Font currentFont = font;
int currentIndex = 0;
void FlushShapeBuffer()
{ {
float fontScale = (float)fontSize / currentFont._fontSize;
hb_buffer_clear_contents(buf); hb_buffer_clear_contents(buf);
hb_buffer_add_utf8(buf, text.Ptr, (.)text.Length, (.)(textBuffer.Ptr - text.Ptr), (.)textBuffer.Length); hb_buffer_add_utf8(buf, text.Ptr, (.)text.Length, (.)(textBuffer.Ptr - text.Ptr), (.)textBuffer.Length);
@@ -143,7 +163,21 @@ namespace GlitchyEngine.Renderer.Text
// Set the script, language and direction of the buffer. // Set the script, language and direction of the buffer.
// TODO: change direction, script, etc. // TODO: change direction, script, etc.
TextDirection direction = textDirectionStack.Back;
switch (direction)
{
case .LeftToRight:
hb_buffer_set_direction(buf, .HB_DIRECTION_LTR); hb_buffer_set_direction(buf, .HB_DIRECTION_LTR);
case .RightToLeft:
hb_buffer_set_direction(buf, .HB_DIRECTION_RTL);
case .TopToBottom:
hb_buffer_set_direction(buf, .HB_DIRECTION_TTB);
case .BottomToTop:
hb_buffer_set_direction(buf, .HB_DIRECTION_BTT);
}
hb_buffer_set_script(buf, .HB_SCRIPT_LATIN); hb_buffer_set_script(buf, .HB_SCRIPT_LATIN);
hb_buffer_set_language(buf, hb_language_from_string("en".CStr(), -1)); hb_buffer_set_language(buf, hb_language_from_string("en".CStr(), -1));
@@ -163,54 +197,73 @@ namespace GlitchyEngine.Renderer.Text
hb_position_t x_advance = glyph_pos[i].x_advance; hb_position_t x_advance = glyph_pos[i].x_advance;
hb_position_t y_advance = glyph_pos[i].y_advance; hb_position_t y_advance = glyph_pos[i].y_advance;
PreparedGlyph glyph = .(font, glyphid, .(penPosition, baseline), scale);//, x_advance / 64, y_advance / 64); PreparedGlyph glyph = .(font, glyphid, .(penPosition, baseline), fontScale);//, x_advance / 64, y_advance / 64);
preparedText.Glyphs.Add(glyph); preparedText.Glyphs.Add(glyph);
penPosition += (x_advance / 64) * scale; penPosition += (x_advance / 64) * fontScale;
baseline += (y_advance / 64) * scale; baseline += (y_advance / 64) * fontScale;
} }
} }
int movedLines = 0;
bool flush = false;
Font currentFont = font;
int currentIndex = 0;
for (char32 char in text.DecodedChars) for (char32 char in text.DecodedChars)
{ {
// TODO: right to left mark (/ embedding?) defer
// TODO: left to right mark (/ embedding?) {
currentIndex = @char.NextIndex;
}
switch(char) switch(char)
{ {
case '\n': case '\n':
// Only flush after the first new line
if (movedLines == 0)
FlushShapeBuffer();
// carriage return // carriage return
movedLines++; movedLines++;
flush = true;
currentIndex = @char.NextIndex;
continue; continue;
case '\u{240}': case '\u{240}':
FlushShapeBuffer();
// carriage return // carriage return
penPosition = 0; penPosition = 0;
flush = true;
currentIndex = @char.NextIndex; continue;
case '\u{2066}':
// LEFT-TO-RIGHT ISOLATE
FlushShapeBuffer();
textDirectionStack.Add(.RightToLeft);
continue;
case '\u{2067}':
// RIGHT-TO-LEFT ISOLATE
FlushShapeBuffer();
textDirectionStack.Add(.RightToLeft);
continue;
// TODO: FIRST STRONG ISOLATE (U+2068)
case '\u{2069}':
// POP DIRECTIONAL ISOLATE
FlushShapeBuffer();
if (textDirectionStack.Count > 1)
textDirectionStack.PopBack();
continue; continue;
} }
// Get the font that can draw the char. Use the given font if no fallback is found (will draw the "missing glyph"). // Get the font that can draw the char. Use the given font if no fallback is found (will draw the "missing glyph").
Font charFont = Font.GetDrawingFont(char, font) ?? font; Font charFont = Font.GetDrawingFont(char, font) ?? font;
if (flush || charFont != font) if (charFont != font)
{ {
float fontScale = (float)fontSize / charFont._fontSize; FlushShapeBuffer();
FlushShapeBuffer(currentFont, fontScale);
currentFont = charFont; currentFont = charFont;
flush = true;
} }
// move baseline if necessary // move baseline if necessary
@@ -232,11 +285,9 @@ namespace GlitchyEngine.Renderer.Text
textBuffer.Ptr = text.Ptr + currentIndex; textBuffer.Ptr = text.Ptr + currentIndex;
} }
textBuffer.Length += @char.NextIndex - currentIndex; textBuffer.Length += @char.NextIndex - currentIndex;
currentIndex = @char.NextIndex;
} }
float fontScale = (float)fontSize / currentFont._fontSize; FlushShapeBuffer();
FlushShapeBuffer(currentFont, fontScale);
return preparedText; return preparedText;
} }
+1 -2
View File
@@ -1,2 +1 @@
I enjoyed staying -- באמת! -- at his house. HalloHalloHallo
I enjoyed staying -- באמת! -- at his house.
+5 -5
View File
@@ -87,7 +87,7 @@ namespace Sandbox
}; };
_depthStencilState = new DepthStencilState(dssDesc); _depthStencilState = new DepthStencilState(dssDesc);
File.ReadAllText("lorem.txt", text); File.ReadAllText("change_direction_test.txt", text);
prepText = FontRenderer.PrepareText(fonty, text, 64, .White, .White); prepText = FontRenderer.PrepareText(fonty, text, 64, .White, .White);
} }
@@ -134,13 +134,13 @@ namespace Sandbox
//FontRenderer.DrawText(fonty, text, 0, 0, 64, .White, .White); //FontRenderer.DrawText(fonty, text, 0, 0, 64, .White, .White);
//var prepared = FontRenderer.PrepareText(fonty,"Hallö!\n gjy ÄA\n\nwww www <--||-->", 64, .White, .White); //var prepared = FontRenderer.PrepareText(fonty,"Hallö!\n gjy ÄA\n\nwww www <--||-->", 64, .White, .White);
//var prepared = FontRenderer.PrepareText(fonty, text, 64, .White, .White); var prepared = FontRenderer.PrepareText(fonty, text, 64, .White, .White);
//var prepared = FontRenderer.PrepareText(fonty,"A\nB", 64, .White, .White); //var prepared = FontRenderer.PrepareText(fonty,"A\nB", 64, .White, .White);
//FontRenderer.DrawText(prepared, 0, 0); FontRenderer.DrawText(prepared, 0, 0);
FontRenderer.DrawText(prepText, 0, 0); //FontRenderer.DrawText(prepText, 0, 0);
//prepared.ReleaseRef(); prepared.ReleaseRef();
Renderer2D.EndScene(); Renderer2D.EndScene();
} }
+4
View File
@@ -4,3 +4,7 @@ Mir geht es gut, danke der Nachfrage. Wie geht es dir?
ÄÖÜüöäßÉéáÁèÈÀàâÊ💕❤ ÄÖÜüöäßÉéáÁèÈÀàâÊ💕❤
λ≙Ω⨁μ×∞ λ≙Ω⨁μ×∞
🤦🏿‍♀️ 🤦🏿‍♀️
I enjoyed staying -- באמת! -- at his house.
I enjoyed staying -- באמת! -- at his house.