diff --git a/GraphicsManager/GraphicsManager.csproj b/GraphicsManager/GraphicsManager.csproj
index b221b32..d54d7d2 100644
--- a/GraphicsManager/GraphicsManager.csproj
+++ b/GraphicsManager/GraphicsManager.csproj
@@ -10,7 +10,7 @@
False
https://git.jacobtech.com/JacobTech.com/GraphicsManager
git
- 1.0.0-beta1
+ 1.0.1-beta01
diff --git a/GraphicsManager/Objects/Core/Font.cs b/GraphicsManager/Objects/Core/Font.cs
index 6a38c40..5e9ea14 100755
--- a/GraphicsManager/Objects/Core/Font.cs
+++ b/GraphicsManager/Objects/Core/Font.cs
@@ -1,25 +1,48 @@
using System.Diagnostics;
using System.Reflection;
+using System.Security.Cryptography;
using SharpFont;
namespace GraphicsManager.Objects.Core;
public class Font
{
- private static List? System = null;
private List _Faces = new();
- private Library lib;
-
- internal Font()
+ internal static Library lib = new();
+ public IReadOnlyList Fonts => _Faces.AsReadOnly();
+ internal static Dictionary AllFileFonts = new();
+ internal static Dictionary AllMemoryFonts = new();
+ internal static List? _SystemPre = null;
+ private static List AllFonts = new();
+ private static bool Backup = false;
+
+ internal void AddSystemFontFace(string path)
+ {
+ Console.WriteLine("Added font: " + path);
+ if (!AllFileFonts.ContainsKey(path)) AllFileFonts.Add(path, new(lib, path, 0));
+ if (!_Faces.Contains(AllFileFonts[path]))
+ {
+ foreach (Font ft in AllFonts)
+ {
+ ft._Faces.Add(AllFileFonts[path]);
+ }
+ }
+ }
+
+ private Font()
{
Name = null!;
Assembly = null!;
Embeded = false;
- if (lib is null) lib = new();
//TODO add more systemfont dection methods
- if (System is null)
+ if (!Backup)
{
- System = new();
+ AllMemoryFonts.Add(SHA256.HashData(Tools.GetResourceBytes("GraphicsManager.Resources.Fonts.TektonPro-Regular.otf")), new Face(lib, Tools.GetResourceBytes("GraphicsManager.Resources.Fonts.TektonPro-Regular.otf"), 0));
+ Backup = true;
+ }
+ if (_SystemPre is null)
+ {
+ _SystemPre = new();
if (OperatingSystem.IsLinux())
{
try
@@ -38,7 +61,7 @@ public class Font
string[] files = proc.StandardOutput.ReadToEnd().Split($": {Environment.NewLine}");
for (int i = 0; i < files.Length; i++)
{
- System!.Add(new Face(lib, files[i], 0));
+ _SystemPre.Add(files[i]);
}
}
catch
@@ -46,11 +69,7 @@ public class Font
}
}
}
-
- for (int i = 0; i < System!.Count; i++) _Faces.Add(System![i]);
- //TODO add a reserved backup font
}
- public IReadOnlyList Faces => _Faces.AsReadOnly();
public void SetEmbeddedFont(string Font, Assembly? Assembly = null)
{
_ = Font ?? throw new ArgumentNullException(nameof(Font));
@@ -59,9 +78,14 @@ public class Font
byte[] f = (Assembly is null
? Tools.GetResourceBytes(Base + Font)
: Tools.GetResourceBytes(Assembly!, $"{Base}{Font}"));
- if (HasTopFont) _Faces[0] = new Face(lib, f, 0);
- else _Faces.Insert(0, new Face(lib, f, 0));
- HasTopFont = true;
+ byte[] hash = SHA256.HashData(f);
+ if (AllMemoryFonts.ContainsKey(hash)) AllMemoryFonts.Add(hash, new(lib, f, 0));
+ if (!_Faces.Contains(AllMemoryFonts[hash])) _Faces.Insert(0, AllMemoryFonts[hash]);
+ else
+ {
+ _Faces.Remove(AllMemoryFonts[hash]);
+ _Faces.Insert(0, AllMemoryFonts[hash]);
+ }
this.Assembly = Assembly;
this.Embeded = true;
this.Name = Font;
@@ -77,17 +101,28 @@ public class Font
Name = Font,
HasTopFont = true
};
+ AllFonts.Add(fontclass);
string Base = "GraphicsManager.Resources.Fonts.";
if (Assembly is not null) Base = string.Empty;
byte[] f = (Assembly is null
? Tools.GetResourceBytes(Base + Font)
: Tools.GetResourceBytes(Assembly!, $"{Base}{Font}"));
- fontclass._Faces.Insert(0, new Face(fontclass.lib, f, 0));
+ byte[] hash = SHA256.HashData(f);
+ if (AllMemoryFonts.ContainsKey(hash)) AllMemoryFonts.Add(hash, new(lib, f, 0));
+ fontclass._Faces.Insert(0, AllMemoryFonts[hash]);
return fontclass;
}
- public static Font MakeFontFromSystem(uint PixelHeight = 20) => new Font() { PixelHeight = PixelHeight};
-
+ private static Font? Cache = null;
+ public static Font MakeFontFromSystem(uint PixelHeight = 20)
+ {
+ if (Cache is null)
+ {
+ Cache = new() { PixelHeight = PixelHeight };
+ AllFonts.Add(Cache);
+ }
+ return Cache;
+ }
public static Font MakeFontFromFile(string Font)
{
_ = Font ?? throw new ArgumentNullException(nameof(Font));
@@ -98,7 +133,8 @@ public class Font
Name = Font,
HasTopFont = true
};
- fontclass._Faces.Insert(0, new Face(fontclass.lib, Font, 0));
+ AllFonts.Add(fontclass);
+ fontclass._Faces.Insert(0, new Face(lib, Font, 0));
return fontclass;
}
diff --git a/GraphicsManager/Objects/Core/Texture.cs b/GraphicsManager/Objects/Core/Texture.cs
index a2f637c..108556d 100755
--- a/GraphicsManager/Objects/Core/Texture.cs
+++ b/GraphicsManager/Objects/Core/Texture.cs
@@ -1,12 +1,24 @@
using GraphicsManager.Structs;
-using OpenTK.Graphics.OpenGL4;
+using OpenTK.Graphics.ES30;
using OpenTK.Mathematics;
using OpenTK.Windowing.Desktop;
using SharpFont;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
+using GL = OpenTK.Graphics.OpenGL4.GL;
using Image = SixLabors.ImageSharp.Image;
+using PixelFormat = OpenTK.Graphics.OpenGL4.PixelFormat;
+using PixelInternalFormat = OpenTK.Graphics.OpenGL4.PixelInternalFormat;
+using PixelStoreParameter = OpenTK.Graphics.OpenGL4.PixelStoreParameter;
+using PixelType = OpenTK.Graphics.OpenGL4.PixelType;
+using TextureMagFilter = OpenTK.Graphics.OpenGL4.TextureMagFilter;
+using TextureMinFilter = OpenTK.Graphics.OpenGL4.TextureMinFilter;
+using TextureParameterName = OpenTK.Graphics.OpenGL4.TextureParameterName;
+using TextureTarget = OpenTK.Graphics.OpenGL4.TextureTarget;
+using TextureUnit = OpenTK.Graphics.OpenGL4.TextureUnit;
+using TextureWrapMode = OpenTK.Graphics.OpenGL4.TextureWrapMode;
+using VertexAttribPointerType = OpenTK.Graphics.OpenGL4.VertexAttribPointerType;
namespace GraphicsManager.Objects.Core;
@@ -46,35 +58,35 @@ public class Texture
{
}
- internal static Character GetChar(Font l, char charter, Face[] faces)
+ internal static Character GetChar(Font l, char charter)
{
- Character t = new();
- for (int i = 0; i < faces.Length; i++)
+ int last = 0;
+ for (int i = 0; i < l.Fonts.Count; i++)
{
try
{
try
{
- faces[i].SetPixelSizes(0, l.PixelHeight);
+ l.Fonts[i].SetPixelSizes(0, l.PixelHeight);
+ last = i;
}
catch (Exception e)
{
continue;
}
- faces[i].SelectCharmap(Encoding.Unicode);
+ l.Fonts[i].SelectCharmap(Encoding.Unicode);
ushort temp = ((ushort)charter);
- if (faces[i].GetCharIndex(temp) == 0) continue;
- faces[i].LoadChar(temp, LoadFlags.Render, LoadTarget.Normal);
- GlyphSlot glyph = faces[i].Glyph;
+ if (l.Fonts[i].GetCharIndex(temp) == 0) continue;
+ l.Fonts[i].LoadChar(temp, LoadFlags.Render, LoadTarget.Normal);
+ GlyphSlot glyph = l.Fonts[i].Glyph;
FTBitmap bitmap = glyph.Bitmap;
- t = new()
+ return new()
{
Size = new Vector2(bitmap.Width, bitmap.Rows),
Bearing = new Vector2(glyph.BitmapLeft, glyph.BitmapTop),
Advance = glyph.Advance.X.Value,
};
- return t;
}
catch (Exception ex)
{
@@ -82,14 +94,65 @@ public class Texture
continue;
}
}
+ for (int i = 0; i < Font._SystemPre.Count; i++)
+ {
+ try
+ {
+ Face tmp = new(Font.lib, Font._SystemPre[i], 0);
+ try
+ {
+ tmp.SetPixelSizes(0, l.PixelHeight);
+ }
+ catch (Exception e)
+ {
+ tmp.Dispose();
+ continue;
+ }
+ tmp.SelectCharmap(Encoding.Unicode);
+ ushort temp2 = ((ushort)charter);
+ if (tmp.GetCharIndex(temp2) == 0)
+ {
+ tmp.Dispose();
+ continue;
+ }
+ tmp.LoadChar(temp2, LoadFlags.Render, LoadTarget.Normal);
+ GlyphSlot glyph2 = tmp.Glyph;
+ FTBitmap bitmap2 = glyph2.Bitmap;
+ l.AddSystemFontFace(Font._SystemPre[i]);
+ return new()
+ {
+ Size = new Vector2(bitmap2.Width, bitmap2.Rows),
+ Bearing = new Vector2(glyph2.BitmapLeft, glyph2.BitmapTop),
+ Advance = glyph2.Advance.X.Value,
+ };
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex);
+ }
+ }
+ l.Fonts[last].SetPixelSizes(0, l.PixelHeight);
+
+ l.Fonts[last].SelectCharmap(Encoding.Unicode);
+ ushort temp22 = ((ushort)charter);
+ l.Fonts[last].LoadChar(temp22, LoadFlags.Render, LoadTarget.Normal);
+ GlyphSlot glyph22 = l.Fonts[0].Glyph;
+ FTBitmap bitmap22 = glyph22.Bitmap;
+
+ return new()
+ {
+ Size = new Vector2(bitmap22.Width, bitmap22.Rows),
+ Bearing = new Vector2(glyph22.BitmapLeft, glyph22.BitmapTop),
+ Advance = (int)glyph22.Advance.X.Value,
+ };
- return t;
}
- internal static Texture TextureForChar(IGLFWGraphicsContext con, Font l, char charter, Face[] faces)
+ internal static Texture TextureForChar(IGLFWGraphicsContext con, Font l, char charter)
{
- Texture t = new();
- for (int i = 0; i < faces.Length; i++)
+ Texture? t = null;
+ int last = 0;
+ for (int i = 0; i < l.Fonts.Count; i++)
{
try
{
@@ -97,7 +160,8 @@ public class Texture
if (Label._characters[con][l].ContainsKey(charter)) return Label._characters[con][l][(ushort)charter].Texture;
try
{
- faces[i].SetPixelSizes(0, l.PixelHeight);
+ l.Fonts[i].SetPixelSizes(0, l.PixelHeight);
+ last = i;
}
catch (Exception e)
{
@@ -108,13 +172,13 @@ public class Texture
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
GL.ActiveTexture(TextureUnit.Texture0);
- faces[i].SelectCharmap(Encoding.Unicode);
+ l.Fonts[i].SelectCharmap(Encoding.Unicode);
ushort temp = ((ushort)charter);
- if (faces[i].GetCharIndex(temp) == 0) continue;
- faces[i].LoadChar(temp, LoadFlags.Render, LoadTarget.Normal);
- GlyphSlot glyph = faces[i].Glyph;
+ if (l.Fonts[i].GetCharIndex(temp) == 0) continue;
+ l.Fonts[i].LoadChar(temp, LoadFlags.Render, LoadTarget.Normal);
+ GlyphSlot glyph = l.Fonts[i].Glyph;
FTBitmap bitmap = glyph.Bitmap;
-
+ t = new();
t.handel = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, t.handel);
GL.TexImage2D(TextureTarget.Texture2D, 0,
@@ -131,6 +195,7 @@ public class Texture
};
Label._characters[con][l].Add(temp, cha);
+ return t;
}
catch (Exception ex)
{
@@ -139,6 +204,91 @@ public class Texture
}
}
+ if (t is null)
+ {
+ for (int i = 0; i < Font._SystemPre.Count; i++)
+ {
+ try
+ {
+ Face tmp = new(Font.lib, Font._SystemPre[i], 0);
+ try
+ {
+ tmp.SetPixelSizes(0, l.PixelHeight);
+ }
+ catch (Exception e)
+ {
+ tmp.Dispose();
+ continue;
+ }
+ GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
+
+ GL.ActiveTexture(TextureUnit.Texture0);
+ tmp.SelectCharmap(Encoding.Unicode);
+ ushort temp2 = ((ushort)charter);
+ if (tmp.GetCharIndex(temp2) == 0)
+ {
+ tmp.Dispose();
+ continue;
+ }
+ tmp.LoadChar(temp2, LoadFlags.Render, LoadTarget.Normal);
+ GlyphSlot glyph2 = tmp.Glyph;
+ FTBitmap bitmap2 = glyph2.Bitmap;
+ l.AddSystemFontFace(Font._SystemPre[i]);
+ t = new();
+ t.handel = GL.GenTexture();
+ GL.BindTexture(TextureTarget.Texture2D, t.handel);
+ GL.TexImage2D(TextureTarget.Texture2D, 0,
+ PixelInternalFormat.R8, bitmap2.Width, bitmap2.Rows, 0,
+ PixelFormat.Red, PixelType.UnsignedByte, bitmap2.Buffer);
+ Character cha2 = new()
+ {
+ Size = new Vector2(bitmap2.Width, bitmap2.Rows),
+ Bearing = new Vector2(glyph2.BitmapLeft, glyph2.BitmapTop),
+ Advance = (int)glyph2.Advance.X.Value,
+ Texture = t,
+ };
+
+ Label._characters[con][l].Add(temp2, cha2);
+ return t;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex);
+ }
+ }
+ if (!Label._characters[con].ContainsKey(l)) Label._characters[con].Add(l, new Dictionary());
+ if (Label._characters[con][l].ContainsKey(charter)) return Label._characters[con][l][(ushort)charter].Texture;
+ l.Fonts[last].SetPixelSizes(0, l.PixelHeight);
+
+
+ GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);
+
+ GL.ActiveTexture(TextureUnit.Texture0);
+ l.Fonts[last].SelectCharmap(Encoding.Unicode);
+ ushort temp = ((ushort)charter);
+ l.Fonts[last].LoadChar(temp, LoadFlags.Render, LoadTarget.Normal);
+ GlyphSlot glyph = l.Fonts[0].Glyph;
+ FTBitmap bitmap = glyph.Bitmap;
+ if (t is null) t = new();
+ else return t;
+ t.handel = GL.GenTexture();
+ GL.BindTexture(TextureTarget.Texture2D, t.handel);
+ GL.TexImage2D(TextureTarget.Texture2D, 0,
+ PixelInternalFormat.R8, bitmap.Width, bitmap.Rows, 0,
+ PixelFormat.Red, PixelType.UnsignedByte, bitmap.Buffer);
+
+
+ Character cha = new()
+ {
+ Size = new Vector2(bitmap.Width, bitmap.Rows),
+ Bearing = new Vector2(glyph.BitmapLeft, glyph.BitmapTop),
+ Advance = (int)glyph.Advance.X.Value,
+ Texture = t,
+ };
+
+ Label._characters[con][l].Add(temp, cha);
+ }
+
return t;
}
diff --git a/GraphicsManager/Objects/Label.cs b/GraphicsManager/Objects/Label.cs
index c0d83d5..a13701d 100755
--- a/GraphicsManager/Objects/Label.cs
+++ b/GraphicsManager/Objects/Label.cs
@@ -15,7 +15,7 @@ namespace GraphicsManager.Objects;
public class Label : IRenderObject
{
public static readonly Dictionary DefaultTextShader = new();
- public static readonly Font DefaultFont = new();
+ public static readonly Font DefaultFont = Font.MakeFontFromSystem();
public ContextMenu? ContextMenu { get; set; } = null;
public IParent? Parent { get; private set; }
public ObjectAnchor Anchor { get; set; } = ObjectAnchor.Left | ObjectAnchor.Top;
@@ -74,7 +74,7 @@ public class Label : IRenderObject
character = value[i];
else
character = PasswordChar.Value;
- Character cha = Texture.GetChar(Font, character, Font.Faces.ToArray());
+ Character cha = Texture.GetChar(Font, character);
if (character == '\n')
{
@@ -155,9 +155,10 @@ public class Label : IRenderObject
c = PasswordChar.Value;
if (!_characters[Window!.Context][Font].ContainsKey(c))
{
- var f = Texture.TextureForChar(Window!.Context, Font, c, Font.Faces.ToArray());
+ var f = Texture.TextureForChar(Window!.Context, Font, c);
f.LoadText();
}
+ if (!_characters[Window!.Context][Font].ContainsKey(c)) continue;
Character ch = _characters[Window!.Context][Font][c];
int maxx = 0;
if (c == '\n')