mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Made FontRenderer static, added scale and linegap to DrawText
it seems I forgot to push the freetype-submodule
This commit is contained in:
@@ -13,3 +13,6 @@
|
|||||||
[submodule "GlitchyEngine\\vendor\\freetype"]
|
[submodule "GlitchyEngine\\vendor\\freetype"]
|
||||||
path = GlitchyEngine\\vendor\\freetype
|
path = GlitchyEngine\\vendor\\freetype
|
||||||
url = https://github.com/aharabada/FreeType-beef.git
|
url = https://github.com/aharabada/FreeType-beef.git
|
||||||
|
[submodule "GlitchyEngine/vendor/freetype"]
|
||||||
|
path = GlitchyEngine/vendor/freetype
|
||||||
|
url = https://github.com/aharabada/FreeType-beef.git
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ namespace GlitchyEngine.Renderer.Text
|
|||||||
{
|
{
|
||||||
internal class GlyphDescriptor
|
internal class GlyphDescriptor
|
||||||
{
|
{
|
||||||
//public FT_Face Face;
|
|
||||||
public Font Font;
|
public Font Font;
|
||||||
|
|
||||||
public FT_UInt GlyphIndex;
|
public FT_UInt GlyphIndex;
|
||||||
@@ -32,13 +31,13 @@ namespace GlitchyEngine.Renderer.Text
|
|||||||
|
|
||||||
private Font _fallback ~ _?.ReleaseRef();
|
private Font _fallback ~ _?.ReleaseRef();
|
||||||
|
|
||||||
private uint32 _fontSize;
|
internal uint32 _fontSize;
|
||||||
private int32 _faceIndex;
|
private int32 _faceIndex;
|
||||||
private bool _hasColor;
|
private bool _hasColor;
|
||||||
|
|
||||||
private Int32_3 _penPos;
|
private Int32_3 _penPos;
|
||||||
private int32 _lastRowHeight;
|
private int32 _lastRowHeight;
|
||||||
private Texture2D _atlas ~ _?.ReleaseRef();
|
internal Texture2D _atlas ~ _?.ReleaseRef();
|
||||||
private Int32_3 _atlasSize;
|
private Int32_3 _atlasSize;
|
||||||
|
|
||||||
private Dictionary<char32, GlyphDescriptor> _glyphs = new .() ~ DeleteDictionaryAndValues!(_);
|
private Dictionary<char32, GlyphDescriptor> _glyphs = new .() ~ DeleteDictionaryAndValues!(_);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using internal GlitchyEngine.Renderer.Text;
|
|||||||
|
|
||||||
namespace GlitchyEngine.Renderer.Text
|
namespace GlitchyEngine.Renderer.Text
|
||||||
{
|
{
|
||||||
public class FontRenderer
|
public static class FontRenderer
|
||||||
{
|
{
|
||||||
internal static FT_Library Library ~ FreeType.Done_FreeType(_);
|
internal static FT_Library Library ~ FreeType.Done_FreeType(_);
|
||||||
|
|
||||||
@@ -21,84 +21,77 @@ namespace GlitchyEngine.Renderer.Text
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private GraphicsContext _context ~ _.ReleaseRef();
|
static this()
|
||||||
|
|
||||||
public this(GraphicsContext context)
|
|
||||||
{
|
{
|
||||||
FontRenderer.InitLibrary();
|
FontRenderer.InitLibrary();
|
||||||
|
|
||||||
_context = context..AddRef();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawText(Renderer2D renderer, Font font, String text, float x, float y, Color fontColor = .White, Color bitmapColor = .White)
|
/** @brief Draws a given text using a specified font stack and renderer.
|
||||||
|
* @param renderer The 2D renderer that will be used to draw the text.
|
||||||
|
* @param font the Fontstack that will be used to draw the text.
|
||||||
|
* @param x The horizontal position of the text (i.e. distance between left side of viewport and the left side of the left-most character, well not really but close enough).
|
||||||
|
* @param y The vertical position of the text (i.e. distance between top side of viewport and the top side of the top-most character, well not really but close enough).
|
||||||
|
* @param fontColor The (default) color used for glyphs that don't have color (e.g. letters or emojies if the font doesn't use bitmaps for them).
|
||||||
|
* @param bitmapColor The (default) color used for glyphs that are bitmaps (e.g. emojies, if the font provies them as bitmap).
|
||||||
|
* @param fontSize The font size in pixels. If set to 0 the default size of the font will be used. Note: due to technical reasons the actual size might deviate from the specified size.
|
||||||
|
* @param lineGapOffset Can be used to manually increase or decrease the gap between lines.
|
||||||
|
*/
|
||||||
|
public static void DrawText(Renderer2D renderer, Font font, String text, float x, float y, Color fontColor = .White, Color bitmapColor = .White, float fontSize = 0, float lineGapOffset = 0)
|
||||||
{
|
{
|
||||||
if(text.IsWhiteSpace)
|
if(text.IsWhiteSpace)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Todo:
|
|
||||||
float scale = 1.0f;
|
float scale = 1.0f;
|
||||||
|
|
||||||
|
if(fontSize != 0)
|
||||||
|
{
|
||||||
|
scale = (float)fontSize / (float)font._fontSize;
|
||||||
|
}
|
||||||
|
|
||||||
// Space between two baselines
|
// Space between two baselines
|
||||||
float linespace = ((font._face.size.metrics.ascender - font._face.size.metrics.descender) >> 6);// + lineGap;
|
float linespace = (((font._face.size.metrics.ascender - font._face.size.metrics.descender) / 64) + lineGapOffset) * scale;
|
||||||
|
|
||||||
// The line we are writing on
|
// The line we are writing on
|
||||||
float baseline = y + linespace;
|
float baseline = y + linespace;
|
||||||
// Where we are writing the next glyph on the line
|
// Position of the next character on the line
|
||||||
float penPosition = x;
|
float penPosition = x;
|
||||||
|
|
||||||
int32 lastLine = 0;
|
// how many lines we moved up or down (e.g. after a \n)
|
||||||
int32 line = 0;
|
int movedLines = 0;
|
||||||
|
|
||||||
List<Texture2D> atlasses = scope .();
|
List<Texture2D> atlasses = scope .();
|
||||||
|
|
||||||
//GlyphDescriptor missingGlyph = font.CharMap.GetValue('\0');
|
// freetype identifies glyphs using utf32 (which makes sense), so we enumerate the text as char32
|
||||||
String.UTF8Enumerator textEnumerator = String.UTF8Enumerator(text, 0, text.Length);
|
for(char32 char in String.UTF8Enumerator(text, 0, text.Length))
|
||||||
for(char32 char in textEnumerator)
|
|
||||||
{
|
{
|
||||||
if(char == '\n')
|
if(char == '\n')
|
||||||
{
|
{
|
||||||
line++;
|
movedLines++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// number of lines that the cursor moved up or down
|
// move baseline if necessary
|
||||||
int32 lineDiff = line - lastLine;
|
if(movedLines != 0)
|
||||||
if(lineDiff != 0)
|
|
||||||
{
|
{
|
||||||
baseline += linespace * lineDiff;
|
// move baseline
|
||||||
|
baseline += linespace * movedLines;
|
||||||
|
|
||||||
// TODO: make carriage return optional?
|
// TODO: make carriage return optional?
|
||||||
penPosition = x;
|
// return pen to start of line
|
||||||
|
penPosition = x;
|
||||||
|
|
||||||
lastLine = line;
|
movedLines = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get glyph from Font
|
// Get glyph from Font
|
||||||
var glyphDesc = font.GetGlyph(char);
|
var glyphDesc = font.GetGlyph(char);
|
||||||
|
|
||||||
// This never happens
|
// This never happens
|
||||||
if(glyphDesc == null)
|
Debug.Assert(glyphDesc != null);
|
||||||
{
|
|
||||||
Debug.Break();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rectangle on the screen
|
Texture2D atlas = glyphDesc.Font._atlas;
|
||||||
Vector4 viewportRect = .(penPosition + (glyphDesc.Metrics.horiBearingX / 64) * scale, baseline - (glyphDesc.Metrics.horiBearingY / 64) * scale, glyphDesc.SizeX * scale, glyphDesc.SizeY * scale);
|
|
||||||
// Rectangle on the font atlas
|
|
||||||
Vector4 texRect = .(glyphDesc.MapCoord.X, glyphDesc.MapCoord.Y, glyphDesc.SizeX, glyphDesc.SizeY);
|
|
||||||
|
|
||||||
Color glyphColor = glyphDesc.IsBitmap ? bitmapColor : fontColor;
|
|
||||||
|
|
||||||
/*
|
|
||||||
if(QueueQuad!(viewportRect, texRect, glyphDesc.MapZ, glyphColor))
|
|
||||||
{
|
|
||||||
DrawQueue(context);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Texture2D atlas = glyphDesc.Font.[Friend]_atlas;
|
|
||||||
|
|
||||||
|
// Add reference to atlas in case it is recreated during rendering
|
||||||
if(!atlasses.Contains(atlas))
|
if(!atlasses.Contains(atlas))
|
||||||
{
|
{
|
||||||
atlasses.Add(atlas..AddRef());
|
atlasses.Add(atlas..AddRef());
|
||||||
@@ -106,6 +99,18 @@ namespace GlitchyEngine.Renderer.Text
|
|||||||
|
|
||||||
Vector2 atlasSize = .(atlas.Width, atlas.Height);
|
Vector2 atlasSize = .(atlas.Width, atlas.Height);
|
||||||
|
|
||||||
|
// Rectangle on the screen
|
||||||
|
Vector4 viewportRect = .(
|
||||||
|
penPosition + (glyphDesc.Metrics.horiBearingX / 64) * scale,
|
||||||
|
baseline - (glyphDesc.Metrics.horiBearingY / 64) * scale,
|
||||||
|
glyphDesc.SizeX * scale,
|
||||||
|
glyphDesc.SizeY * scale);
|
||||||
|
|
||||||
|
// Rectangle on the font atlas
|
||||||
|
Vector4 texRect = .(glyphDesc.MapCoord.X, glyphDesc.MapCoord.Y, glyphDesc.SizeX, glyphDesc.SizeY);
|
||||||
|
|
||||||
|
Color glyphColor = glyphDesc.IsBitmap ? bitmapColor : fontColor;
|
||||||
|
|
||||||
texRect /= Vector4(atlasSize, atlasSize);
|
texRect /= Vector4(atlasSize, atlasSize);
|
||||||
|
|
||||||
renderer.Draw(atlas, viewportRect.X, viewportRect.Y, viewportRect.Z, viewportRect.W, glyphColor, 0.0f, texRect);
|
renderer.Draw(atlas, viewportRect.X, viewportRect.Y, viewportRect.Z, viewportRect.W, glyphColor, 0.0f, texRect);
|
||||||
@@ -115,6 +120,7 @@ namespace GlitchyEngine.Renderer.Text
|
|||||||
|
|
||||||
renderer.End();
|
renderer.End();
|
||||||
|
|
||||||
|
// release all atlas textures
|
||||||
for(int i < atlasses.Count)
|
for(int i < atlasses.Count)
|
||||||
{
|
{
|
||||||
atlasses[i].ReleaseRef();
|
atlasses[i].ReleaseRef();
|
||||||
|
|||||||
+1
Submodule GlitchyEngine/vendor/freetype added at 8b289627bd
@@ -9,6 +9,7 @@ using GlitchyEngine.Renderer;
|
|||||||
using GlitchyEngine.Math;
|
using GlitchyEngine.Math;
|
||||||
using GlitchyEngine.World;
|
using GlitchyEngine.World;
|
||||||
using GlitchyEngine.Renderer.Text;
|
using GlitchyEngine.Renderer.Text;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace Sandbox
|
namespace Sandbox
|
||||||
{
|
{
|
||||||
@@ -60,6 +61,8 @@ namespace Sandbox
|
|||||||
|
|
||||||
Texture2D _testTexture ~ _?.ReleaseRef();
|
Texture2D _testTexture ~ _?.ReleaseRef();
|
||||||
|
|
||||||
|
String testText ~ delete _;
|
||||||
|
|
||||||
[AllowAppend]
|
[AllowAppend]
|
||||||
public this() : base("Example")
|
public this() : base("Example")
|
||||||
{
|
{
|
||||||
@@ -119,16 +122,20 @@ namespace Sandbox
|
|||||||
_testTexture.SetData<Color>(&colors, 0, 1, 1, 1);
|
_testTexture.SetData<Color>(&colors, 0, 1, 1, 1);
|
||||||
|
|
||||||
fonty = new Font(_context, "C:\\Windows\\Fonts\\arial.ttf", 64, true, 'A', 16);
|
fonty = new Font(_context, "C:\\Windows\\Fonts\\arial.ttf", 64, true, 'A', 16);
|
||||||
|
var japanese = new Font(_context, "C:\\Windows\\Fonts\\YuGothM.ttc", 64, true, '\0', 1);
|
||||||
var emojis = new Font(_context, "C:\\Windows\\Fonts\\seguiemj.ttf", 64, true, '😂' - 10, 1);
|
var emojis = new Font(_context, "C:\\Windows\\Fonts\\seguiemj.ttf", 64, true, '😂' - 10, 1);
|
||||||
fonty.Fallback = emojis..ReleaseRefNoDelete();
|
var mathstuff = new Font(_context, "C:\\Windows\\Fonts\\cambria.ttc", 64, true, 'α', 1);
|
||||||
|
fonty.Fallback = japanese..ReleaseRefNoDelete();
|
||||||
|
japanese.Fallback = emojis..ReleaseRefNoDelete();
|
||||||
|
emojis.Fallback = mathstuff..ReleaseRefNoDelete();
|
||||||
|
|
||||||
fontRenderer = new FontRenderer(_context);
|
// Load test text
|
||||||
|
var result = File.ReadAllText("test.txt", testText = new String(), true);
|
||||||
|
//Log.EngineLogger.Assert(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
Font fonty ~ _.ReleaseRef();
|
Font fonty ~ _.ReleaseRef();
|
||||||
|
|
||||||
FontRenderer fontRenderer ~ delete _;
|
|
||||||
|
|
||||||
VertexLayout layout ~ delete _;
|
VertexLayout layout ~ delete _;
|
||||||
|
|
||||||
GeometryBinding quadBinding ~ _?.ReleaseRef();
|
GeometryBinding quadBinding ~ _?.ReleaseRef();
|
||||||
@@ -304,7 +311,8 @@ namespace Sandbox
|
|||||||
_alphaBlendState.Bind();
|
_alphaBlendState.Bind();
|
||||||
Renderer2D.Begin(.FrontToBack, .(_context.SwapChain.Width, _context.SwapChain.Height));
|
Renderer2D.Begin(.FrontToBack, .(_context.SwapChain.Width, _context.SwapChain.Height));
|
||||||
|
|
||||||
fontRenderer.DrawText(Renderer2D, fonty, "Hallo Welt, wie geht es dir? 😂😂😂\nMir geht es gut, danke der Nachfrage, wie geht es dir?\nMir geht es hervorragend: Meine Engine kann endlich Text rendern\n und es scheint ganz in ordnung zu sein.", 0, 0);
|
// Hallo Welt, wie geht es dir? 😂😂😂\nMir geht es gut, danke der Nachfrage. Wie geht es dir?\nMir geht es hervorragend und besser noch: meine Engine kann endlich Text rendern!💕❤\n und es scheint ganz in ordnung zu sein.
|
||||||
|
FontRenderer.DrawText(Renderer2D, fonty, testText, 0, 0, .White, .White, 32);
|
||||||
|
|
||||||
Renderer2D.End();
|
Renderer2D.End();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
Hello World, how are you? 😂😂😂
|
||||||
|
Mir geht es gut, danke der Nachfrage. Wie geht es dir?
|
||||||
|
順調に進んでいますし、何よりもエンジンがやっと文字を表示できるようになりました。
|
||||||
|
ÄÖÜüöäßÉéáÁèÈÀàâÊ💕❤
|
||||||
|
λ≙Ω⨁μ×∞
|
||||||
Reference in New Issue
Block a user