Remove old test projects.
This commit is contained in:
		
							parent
							
								
									41b7bebba5
								
							
						
					
					
						commit
						8d2afd0955
					
				@ -1,83 +0,0 @@
 | 
				
			|||||||
using System;
 | 
					 | 
				
			||||||
using System.Runtime.InteropServices;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Quik.FreeType
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public static class FT
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        private const string freetype2 = "freetype";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [DllImport(freetype2, EntryPoint = "FT_Init_FreeType")]
 | 
					 | 
				
			||||||
        public static extern FTError InitFreeType(out FTLibrary library);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [DllImport(freetype2, EntryPoint = "FT_Done_FreeType")]
 | 
					 | 
				
			||||||
        public static extern FTError DoneFreeType(FTLibrary library);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [DllImport(freetype2, EntryPoint = "FT_New_Face")]
 | 
					 | 
				
			||||||
        public static extern FTError NewFace(
 | 
					 | 
				
			||||||
            FTLibrary library,
 | 
					 | 
				
			||||||
            [MarshalAs(UnmanagedType.LPStr)] string path,
 | 
					 | 
				
			||||||
            long faceIndex,
 | 
					 | 
				
			||||||
            out FTFace face);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [DllImport(freetype2, EntryPoint = "FT_New_Memory_Face")]
 | 
					 | 
				
			||||||
        public static extern FTError NewMemoryFace(
 | 
					 | 
				
			||||||
            FTLibrary library,
 | 
					 | 
				
			||||||
            IntPtr buffer,
 | 
					 | 
				
			||||||
            long size,
 | 
					 | 
				
			||||||
            long faceIndex,
 | 
					 | 
				
			||||||
            out FTFace face);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [DllImport(freetype2, EntryPoint = "FT_New_Memory_Face")]
 | 
					 | 
				
			||||||
        public static extern FTError NewMemoryFace(
 | 
					 | 
				
			||||||
            FTLibrary library,
 | 
					 | 
				
			||||||
            [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] buffer,
 | 
					 | 
				
			||||||
            long size,
 | 
					 | 
				
			||||||
            long faceIndex,
 | 
					 | 
				
			||||||
            out FTFace face);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [DllImport(freetype2, EntryPoint = "FT_New_Memory_Face")]
 | 
					 | 
				
			||||||
        public static extern FTError NewMemoryFace(
 | 
					 | 
				
			||||||
            FTLibrary library,
 | 
					 | 
				
			||||||
            [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] Span<byte> buffer,
 | 
					 | 
				
			||||||
            long size,
 | 
					 | 
				
			||||||
            long faceIndex,
 | 
					 | 
				
			||||||
            out FTFace face);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // public static extern FTError OpenFace(FTLibrary library, in FTOpenArgs args, long faceIndex, out FTFace face);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // [DllImport(freetype2, EntryPoint = "FT_Attach_File")]
 | 
					 | 
				
			||||||
        // public static extern FTError AttachFile(FTFace face, [MarshalAs(UnmanagedType.LPStr)] string filePathName);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [DllImport(freetype2, EntryPoint = "FT_Set_Char_Size")]
 | 
					 | 
				
			||||||
        public static extern FTError SetCharSize(
 | 
					 | 
				
			||||||
            FTFace library,
 | 
					 | 
				
			||||||
            long charWidth,
 | 
					 | 
				
			||||||
            long charHeight,
 | 
					 | 
				
			||||||
            uint horizontalResolution,
 | 
					 | 
				
			||||||
            uint verticalResolution);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [DllImport(freetype2, EntryPoint = "FT_Get_Char_Index")]
 | 
					 | 
				
			||||||
        public static extern uint GetCharIndex(FTFace face, ulong charCode);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [DllImport(freetype2, EntryPoint = "FT_Load_Glyph")]
 | 
					 | 
				
			||||||
        public static extern FTError LoadGlyph(FTFace face, uint charIndex, FTLoadFlags flags);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [DllImport(freetype2, EntryPoint = "FT_Render_Glyph")]
 | 
					 | 
				
			||||||
        public static extern FTError RenderGlyph(FTGlyphSlot slot, FTRenderMode mode);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [DllImport(freetype2, EntryPoint = "FT_Done_Face")]
 | 
					 | 
				
			||||||
        public static extern FTError DoneFace(FTFace face);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [DllImport(freetype2, EntryPoint = "FT_Bitmap_Init")]
 | 
					 | 
				
			||||||
        public static extern void BitmapInit(ref FTBitmap bitmap);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [DllImport(freetype2, EntryPoint = "FT_Bitmap_Convert")]
 | 
					 | 
				
			||||||
        public static extern void BitmapConvert(FTLibrary library, in FTBitmap source, ref FTBitmap target,
 | 
					 | 
				
			||||||
            int alignment);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [DllImport(freetype2, EntryPoint = "FT_Bitmap_Done")]
 | 
					 | 
				
			||||||
        public static extern void BitmapDone(FTLibrary library, ref FTBitmap bitmap);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,7 +0,0 @@
 | 
				
			|||||||
namespace Quik.FreeType
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public enum FTError : int
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        None = 0,
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,28 +0,0 @@
 | 
				
			|||||||
using System;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Quik.FreeType
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    [Flags]
 | 
					 | 
				
			||||||
    public enum FTLoadFlags
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        Default = 0,
 | 
					 | 
				
			||||||
        NoScale = 1 << 0,
 | 
					 | 
				
			||||||
        NoHinting = 1 << 1,
 | 
					 | 
				
			||||||
        Render = 1 << 2,
 | 
					 | 
				
			||||||
        NoBitmap = 1 << 3,
 | 
					 | 
				
			||||||
        VerticalLayout = 1 << 4,
 | 
					 | 
				
			||||||
        ForceAutoHint = 1 << 5,
 | 
					 | 
				
			||||||
        CropBitmap = 1 << 6,
 | 
					 | 
				
			||||||
        Pedantic =  1 << 7,
 | 
					 | 
				
			||||||
        IgnoreGlobalAdvanceWidth = 1 << 9,
 | 
					 | 
				
			||||||
        NoRecurse = 1 << 10,
 | 
					 | 
				
			||||||
        IgnoreTransform = 1 << 11,
 | 
					 | 
				
			||||||
        Monochrome= 1 << 12,
 | 
					 | 
				
			||||||
        LinearDesign = 1 << 13,
 | 
					 | 
				
			||||||
        SbitsOnly = 1 << 14,
 | 
					 | 
				
			||||||
        NoAutoHint = 1 << 15,
 | 
					 | 
				
			||||||
        Color = 1 << 20,
 | 
					 | 
				
			||||||
        ComputeMetrics = 1 << 21,
 | 
					 | 
				
			||||||
        BitmapMetricsOnly = 1 << 22
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,12 +0,0 @@
 | 
				
			|||||||
namespace Quik.FreeType
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public enum FTRenderMode
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        Normal = 0,
 | 
					 | 
				
			||||||
        Light,
 | 
					 | 
				
			||||||
        Mono,
 | 
					 | 
				
			||||||
        Lcd,
 | 
					 | 
				
			||||||
        LcdVertical,
 | 
					 | 
				
			||||||
        Sdf
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,28 +0,0 @@
 | 
				
			|||||||
using System;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Quik.FreeType
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    [Flags]
 | 
					 | 
				
			||||||
    public enum FaceFlag : int
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        Scalable = 1 << 0,
 | 
					 | 
				
			||||||
        FixedSizes = 1 << 1,
 | 
					 | 
				
			||||||
        FixedWidth = 1 << 2,
 | 
					 | 
				
			||||||
        Sfnt = 1 << 3,
 | 
					 | 
				
			||||||
        Horizontal = 1 << 4,
 | 
					 | 
				
			||||||
        Vertical = 1 << 5,
 | 
					 | 
				
			||||||
        Kerning = 1 << 6,
 | 
					 | 
				
			||||||
        FastGlyphs = 1 << 7,
 | 
					 | 
				
			||||||
        MultipleMasters = 1 << 8,
 | 
					 | 
				
			||||||
        GlyphNames = 1 << 9,
 | 
					 | 
				
			||||||
        ExternalStream = 1 << 10,
 | 
					 | 
				
			||||||
        Hinter = 1 << 11,
 | 
					 | 
				
			||||||
        CidKeyed = 1 << 12,
 | 
					 | 
				
			||||||
        Tricky = 1 << 13,
 | 
					 | 
				
			||||||
        Color = 1 << 14,
 | 
					 | 
				
			||||||
        Variation =  1 << 15,
 | 
					 | 
				
			||||||
        Svg = 1 << 16,
 | 
					 | 
				
			||||||
        Sbix = 1 << 17,
 | 
					 | 
				
			||||||
        SbixOverlay = 1 << 18
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,181 +0,0 @@
 | 
				
			|||||||
using System;
 | 
					 | 
				
			||||||
using System.Collections.Generic;
 | 
					 | 
				
			||||||
using System.IO;
 | 
					 | 
				
			||||||
using Quik.Typography;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Quik.FreeType
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public class FreeTypeFont : QuikFont, IDisposable
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private FreeTypeFontManager _owner;
 | 
					 | 
				
			||||||
        private FTLibrary _library;
 | 
					 | 
				
			||||||
        private FTFace _face;
 | 
					 | 
				
			||||||
        private List<Atlas> _textures = new List<Atlas>();
 | 
					 | 
				
			||||||
        private Dictionary<int, GlyphEntry> _entries = new Dictionary<int, GlyphEntry>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public override float Ascender => _face.ScaledSize.Ascender / 64f;
 | 
					 | 
				
			||||||
        public override float Descender => _face.ScaledSize.Descender / 64f;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        internal FreeTypeFont(FreeTypeFontManager owner, FileInfo file, QuikFontStyle style)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            Style = style;
 | 
					 | 
				
			||||||
            _owner = owner;
 | 
					 | 
				
			||||||
            _library = owner._library;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (FT.NewFace(_library, file.FullName, 0, out _face) != FTError.None)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                throw new Exception("Could not load font file.");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            FT.SetCharSize(_face, 0, (long)(style.Size * 64), 96, 96);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            _textures.Add(new Atlas(owner.Context.TextureManager, _library));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public override QuikFontStyle Style { get; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public override bool HasCharacter(int character)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return FT.GetCharIndex(_face, (ulong)character) != 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public override void GetCharacter(int character, out QuikTexture texture, out QuikGlyph glyph)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            GlyphEntry entry;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (_entries.TryGetValue(character, out entry))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                texture = entry.Atlas.Texture;
 | 
					 | 
				
			||||||
                glyph = entry.Metrics;
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            entry = new GlyphEntry();
 | 
					 | 
				
			||||||
            entry.Character = character;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            uint index = FT.GetCharIndex(_face, (ulong) character);
 | 
					 | 
				
			||||||
            FT.LoadGlyph(_face, index, FTLoadFlags.Default);
 | 
					 | 
				
			||||||
            FT.RenderGlyph(_face.Glyph, FTRenderMode.Normal);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            entry.Atlas = _textures[_textures.Count - 1];
 | 
					 | 
				
			||||||
            if (!entry.Atlas.CanFit(_face.Glyph))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                entry.Atlas = new Atlas(_owner.Context.TextureManager, _library);
 | 
					 | 
				
			||||||
                _textures.Add(entry.Atlas);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            entry.Atlas.AttachGlyph(_face.Glyph, out QRectangle uvs);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            entry.Metrics = new QuikGlyph(
 | 
					 | 
				
			||||||
                character,
 | 
					 | 
				
			||||||
                uvs,
 | 
					 | 
				
			||||||
                new QVec2(_face.Glyph.Metrics.Width / 64f, _face.Glyph.Metrics.Height / 64f),
 | 
					 | 
				
			||||||
                new QVec2(_face.Glyph.Metrics.HorizontalBearingX / 64f, _face.Glyph.Metrics.HorizontalBearingY / 64f),
 | 
					 | 
				
			||||||
                new QVec2(_face.Glyph.Metrics.VerticalBearingX / 64f , _face.Glyph.Metrics.VerticalBearingY / 64f),
 | 
					 | 
				
			||||||
                new QVec2(_face.Glyph.Metrics.HorizontalAdvance / 64f, _face.Glyph.Metrics.VerticalAdvance / 64f));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            _entries[character] = entry;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            texture = entry.Atlas.Texture;
 | 
					 | 
				
			||||||
            glyph = entry.Metrics;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public bool IsDisposed { get; private set; } = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private void Dispose(bool disposing)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (IsDisposed) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (disposing)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                foreach (Atlas atlas in _textures)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    atlas.Dispose();
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            FT.DoneFace(_face);
 | 
					 | 
				
			||||||
            IsDisposed = true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public void Dispose() => Dispose(true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private class Atlas : IDisposable
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            public QuikTexture Texture;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            private QVec2 _pointer = new QVec2();
 | 
					 | 
				
			||||||
            private float _verticalAdvance = 0;
 | 
					 | 
				
			||||||
            private FTLibrary _ft;
 | 
					 | 
				
			||||||
            private FTBitmap _bitmap;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            public Atlas(IQuikTextureManager textureManager, FTLibrary ft)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                Texture = textureManager.CreateTexture(
 | 
					 | 
				
			||||||
                    new QVec2(4096, 4096),
 | 
					 | 
				
			||||||
                    false,
 | 
					 | 
				
			||||||
                    QuikImageFormat.RgbaU8);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                FT.BitmapInit(ref _bitmap);
 | 
					 | 
				
			||||||
                _ft = ft;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            public bool CanFit(in FTGlyphSlot slot)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                // FIXME: the atlas will overflow.
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            public void AttachGlyph(in FTGlyphSlot slot, out QRectangle UVs)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                FT.BitmapConvert(_ft, slot.Bitmap, ref _bitmap, 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                QRectangle position =
 | 
					 | 
				
			||||||
                    new QRectangle(
 | 
					 | 
				
			||||||
                        _pointer + new QVec2(_bitmap.Width + 1, _bitmap.Rows + 1),
 | 
					 | 
				
			||||||
                        _pointer + new QVec2(1, 1));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                Texture.SubImage(
 | 
					 | 
				
			||||||
                    _bitmap.Buffer,
 | 
					 | 
				
			||||||
                    QuikImageFormat.AlphaU8, 
 | 
					 | 
				
			||||||
                    position,
 | 
					 | 
				
			||||||
                    0,
 | 
					 | 
				
			||||||
                    1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                _pointer.X += _bitmap.Width + 2;
 | 
					 | 
				
			||||||
                _verticalAdvance = Math.Max(_verticalAdvance, slot.Bitmap.Rows + 2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                UVs = new QRectangle(
 | 
					 | 
				
			||||||
                    position.Right / 4096,
 | 
					 | 
				
			||||||
                    position.Bottom / 4096,
 | 
					 | 
				
			||||||
                    position.Left / 4096,
 | 
					 | 
				
			||||||
                    position.Top / 4096
 | 
					 | 
				
			||||||
                    );
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            private bool _isDisposed = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            public void Dispose(bool disposing)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (_isDisposed) return;
 | 
					 | 
				
			||||||
                if (disposing)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    Texture.Dispose();
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                FT.BitmapDone(_ft, ref _bitmap);
 | 
					 | 
				
			||||||
                _isDisposed = true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            public void Dispose()
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private class GlyphEntry
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            public int Character;
 | 
					 | 
				
			||||||
            public Atlas Atlas;
 | 
					 | 
				
			||||||
            public QuikGlyph Metrics;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,177 +0,0 @@
 | 
				
			|||||||
using System;
 | 
					 | 
				
			||||||
using System.Collections.Generic;
 | 
					 | 
				
			||||||
using System.IO;
 | 
					 | 
				
			||||||
using Quik.Typography;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Quik.FreeType
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public class FreeTypeFontManager : IQuikFontManager, IDisposable
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public QuikContext Context { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        internal FTLibrary _library;
 | 
					 | 
				
			||||||
        private Dictionary<string, FontCacheEntry> _cache = new Dictionary<string, FontCacheEntry>();
 | 
					 | 
				
			||||||
        private Dictionary<QuikFontStyle, FreeTypeFont> _fonts= new Dictionary<QuikFontStyle, FreeTypeFont>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public event FreeTypeFontManagerFontFinder FontNotFound;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public FreeTypeFontManager()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            FT.InitFreeType(out _library);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // FIXME: There are operating system specific ways to achieve this. This is
 | 
					 | 
				
			||||||
            // definitely not the best way to do this.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Scan the fonts folder and build up a font cache.
 | 
					 | 
				
			||||||
            string path = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);
 | 
					 | 
				
			||||||
            if (string.IsNullOrEmpty(path))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (OperatingSystem.IsLinux())
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    path = "/usr/share/fonts";
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else if (OperatingSystem.IsWindows())
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    path = Path.Combine(
 | 
					 | 
				
			||||||
                        Environment.GetFolderPath(Environment.SpecialFolder.Windows),
 | 
					 | 
				
			||||||
                        "Fonts");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                // For macOS I don't know. Too bad.
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            DirectoryInfo directory = new DirectoryInfo(path);
 | 
					 | 
				
			||||||
            ScanDirectoryForFonts(directory);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private void ScanDirectoryForFonts(DirectoryInfo directory)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            foreach (FileSystemInfo node in directory.GetFileSystemInfos())
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (node.Attributes.HasFlag(FileAttributes.Directory))
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    ScanDirectoryForFonts(node as DirectoryInfo);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    ScanFileForFonts(node as FileInfo);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private void ScanFileForFonts(FileInfo file)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (file is null) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (FT.NewFace(_library, file.FullName, 0, out FTFace face) == FTError.None)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                FontCacheEntry entry;
 | 
					 | 
				
			||||||
                string name = face.FamilyName;
 | 
					 | 
				
			||||||
                string style = face.StyleName;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (name is null)
 | 
					 | 
				
			||||||
                    goto done_face;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (_cache.ContainsKey(name))
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    entry = _cache[name];
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    entry = new FontCacheEntry();
 | 
					 | 
				
			||||||
                    entry.Family = name;
 | 
					 | 
				
			||||||
                    _cache[name] = entry;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                switch (style.ToLowerInvariant())
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                case "regular":
 | 
					 | 
				
			||||||
                    entry.Regular = file;
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                case "bold":
 | 
					 | 
				
			||||||
                    entry.Bold = file;
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                case "italic":
 | 
					 | 
				
			||||||
                    entry.Italic = file;
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
            done_face:
 | 
					 | 
				
			||||||
                FT.DoneFace(face);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public void Clear()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            // Nothing to do.
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public QuikFont GetFont(QuikFontStyle fontStyle)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            FreeTypeFont font;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (_fonts.TryGetValue(fontStyle, out font))
 | 
					 | 
				
			||||||
                return font;
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            FileInfo file = FindFont(fontStyle);
 | 
					 | 
				
			||||||
            if (file == null)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                FontNotFound?.Invoke(fontStyle, ref file);
 | 
					 | 
				
			||||||
                if (file == null)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    throw new Exception("Could not find the font you are looking for.");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            font = new FreeTypeFont(this, file, fontStyle);
 | 
					 | 
				
			||||||
            _fonts.Add(fontStyle, font);
 | 
					 | 
				
			||||||
            return font;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private FileInfo FindFont(QuikFontStyle fontStyle)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            FontCacheEntry entry;
 | 
					 | 
				
			||||||
            if (_cache.TryGetValue(fontStyle.Family, out entry))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                switch (fontStyle.Type)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                case QuikFontType.Normal:
 | 
					 | 
				
			||||||
                    return entry.Regular;
 | 
					 | 
				
			||||||
                case QuikFontType.Bold:
 | 
					 | 
				
			||||||
                    return entry.Bold;
 | 
					 | 
				
			||||||
                case QuikFontType.Italic:
 | 
					 | 
				
			||||||
                    return entry.Italic;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return null;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // IDisposable
 | 
					 | 
				
			||||||
        private void ReleaseUnmanagedResources()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            FT.DoneFreeType(_library);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public void Dispose()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            ReleaseUnmanagedResources();
 | 
					 | 
				
			||||||
            GC.SuppressFinalize(this);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ~FreeTypeFontManager()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            ReleaseUnmanagedResources();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private class FontCacheEntry
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            public string Family;
 | 
					 | 
				
			||||||
            public FileInfo Regular;
 | 
					 | 
				
			||||||
            public FileInfo Bold;
 | 
					 | 
				
			||||||
            public FileInfo Italic;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public delegate void FreeTypeFontManagerFontFinder(QuikFontStyle style, ref FileInfo info);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,13 +0,0 @@
 | 
				
			|||||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <PropertyGroup>
 | 
					 | 
				
			||||||
        <TargetFramework>net6.0</TargetFramework>
 | 
					 | 
				
			||||||
        <LangVersion>7.3</LangVersion>
 | 
					 | 
				
			||||||
        <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
 | 
					 | 
				
			||||||
    </PropertyGroup>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <ItemGroup>
 | 
					 | 
				
			||||||
      <ProjectReference Include="..\Quik\Quik.csproj" />
 | 
					 | 
				
			||||||
    </ItemGroup>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</Project>
 | 
					 | 
				
			||||||
@ -1,180 +0,0 @@
 | 
				
			|||||||
using System;
 | 
					 | 
				
			||||||
using System.Runtime.InteropServices;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Quik.FreeType
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public struct FTLibrary
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        private IntPtr _handle;
 | 
					 | 
				
			||||||
        public IntPtr Handle => _handle;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public unsafe struct FTFace
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        private IntPtr _handle;
 | 
					 | 
				
			||||||
        public IntPtr Handle => _handle;
 | 
					 | 
				
			||||||
        private unsafe FTFaceInternal* Ptr => (FTFaceInternal*)_handle;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public long NumberOfGlyphs => Ptr->NumberOfGlyphs;
 | 
					 | 
				
			||||||
        public long FaceIndex => Ptr->FaceIndex;
 | 
					 | 
				
			||||||
        public FaceFlag FaceFlags => (FaceFlag)Ptr->FaceFlags;
 | 
					 | 
				
			||||||
        public long StyleFlags => Ptr->StyleFlags;
 | 
					 | 
				
			||||||
        public string FamilyName => Marshal.PtrToStringUTF8(Ptr->FamilyName);
 | 
					 | 
				
			||||||
        public string StyleName => Marshal.PtrToStringUTF8(Ptr->StyleName);
 | 
					 | 
				
			||||||
        public int NumberOfFixedSizes => Ptr->NumberOfFixedSizes;
 | 
					 | 
				
			||||||
        public int NumberOfCharMaps => Ptr->NumberOfCharMaps;
 | 
					 | 
				
			||||||
        public FTGlyphSlot Glyph => Ptr->Glyph;
 | 
					 | 
				
			||||||
        public short Ascender => Ptr->Ascender;
 | 
					 | 
				
			||||||
        public short Descender => Ptr->Descender;
 | 
					 | 
				
			||||||
        public ref readonly FTSizeMetrics ScaledSize => ref ((FTSize*)Ptr->Size)->Metrics;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public struct FTBox
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public long XMin;
 | 
					 | 
				
			||||||
        public long YMin;
 | 
					 | 
				
			||||||
        public long XMax;
 | 
					 | 
				
			||||||
        public long YMax;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    internal struct FTFaceInternal
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public long NumberOfFaces;
 | 
					 | 
				
			||||||
        public long FaceIndex;
 | 
					 | 
				
			||||||
        public long FaceFlags;
 | 
					 | 
				
			||||||
        public long StyleFlags;
 | 
					 | 
				
			||||||
        public long NumberOfGlyphs;
 | 
					 | 
				
			||||||
        public IntPtr FamilyName;
 | 
					 | 
				
			||||||
        public IntPtr StyleName;
 | 
					 | 
				
			||||||
        public int NumberOfFixedSizes;
 | 
					 | 
				
			||||||
        public IntPtr AvailableSizes;
 | 
					 | 
				
			||||||
        public int NumberOfCharMaps;
 | 
					 | 
				
			||||||
        public IntPtr Charmaps;
 | 
					 | 
				
			||||||
        public FTGeneric Generic;
 | 
					 | 
				
			||||||
        public FTBox BoundingBox;
 | 
					 | 
				
			||||||
        public ushort UnitsPerEm;
 | 
					 | 
				
			||||||
        public short Ascender;
 | 
					 | 
				
			||||||
        public short Descender;
 | 
					 | 
				
			||||||
        public short Height;
 | 
					 | 
				
			||||||
        public short MaxAdvanceWidth;
 | 
					 | 
				
			||||||
        public short MaxAdvanceHeight;
 | 
					 | 
				
			||||||
        public short UnderlinePosition;
 | 
					 | 
				
			||||||
        public short UnderlineThickness;
 | 
					 | 
				
			||||||
        public FTGlyphSlot Glyph;
 | 
					 | 
				
			||||||
        public IntPtr Size;
 | 
					 | 
				
			||||||
        public IntPtr Charmap;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Rest of the struct is private to implementation.
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public struct FTGeneric
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public IntPtr Data;
 | 
					 | 
				
			||||||
        public IntPtr Finalizer;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public struct FTVector
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public long X;
 | 
					 | 
				
			||||||
        public long Y;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public struct FTBitmap
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public uint Rows;
 | 
					 | 
				
			||||||
        public uint Width;
 | 
					 | 
				
			||||||
        public int Pitch;
 | 
					 | 
				
			||||||
        public IntPtr Buffer;
 | 
					 | 
				
			||||||
        public ushort NumberOfGrays;
 | 
					 | 
				
			||||||
        public byte PixelMode;
 | 
					 | 
				
			||||||
        public byte PaletteMode;
 | 
					 | 
				
			||||||
        public IntPtr Palette;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public struct FTOutline
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public short NumberOfContours;
 | 
					 | 
				
			||||||
        public short NumberOfPoints;
 | 
					 | 
				
			||||||
        public IntPtr Points;
 | 
					 | 
				
			||||||
        public IntPtr Tags;
 | 
					 | 
				
			||||||
        public IntPtr Contours;
 | 
					 | 
				
			||||||
        public int Flags;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    internal struct FTGlyphSlotInternal
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public FTLibrary Library;
 | 
					 | 
				
			||||||
        public FTFace Face;
 | 
					 | 
				
			||||||
        public FTGlyphSlot Next;
 | 
					 | 
				
			||||||
        public uint GlyphIndex;
 | 
					 | 
				
			||||||
        public FTGeneric Generic;
 | 
					 | 
				
			||||||
        public FTGlyphMetrics Metrics;
 | 
					 | 
				
			||||||
        public long LinearHorizontalAdvance;
 | 
					 | 
				
			||||||
        public long LinearVerticalAdvance;
 | 
					 | 
				
			||||||
        public FTVector Advance;
 | 
					 | 
				
			||||||
        public int Format;
 | 
					 | 
				
			||||||
        public FTBitmap Bitmap;
 | 
					 | 
				
			||||||
        public int BitmapLeft;
 | 
					 | 
				
			||||||
        public int BitmapTop;
 | 
					 | 
				
			||||||
        public FTOutline Outline;
 | 
					 | 
				
			||||||
        public uint NumberOfSubGlyphs;
 | 
					 | 
				
			||||||
        public IntPtr SubGlyphs;
 | 
					 | 
				
			||||||
        public IntPtr ControlData;
 | 
					 | 
				
			||||||
        public long ControlLength;
 | 
					 | 
				
			||||||
        public long LsbDelta;
 | 
					 | 
				
			||||||
        public long RsbDelta;
 | 
					 | 
				
			||||||
        public IntPtr Other;
 | 
					 | 
				
			||||||
        public IntPtr Internal;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public unsafe struct FTGlyphSlot
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        private IntPtr _handle;
 | 
					 | 
				
			||||||
        public IntPtr Handle => _handle;
 | 
					 | 
				
			||||||
        private FTGlyphSlotInternal* Ptr => (FTGlyphSlotInternal*) _handle;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public FTLibrary Library => Ptr->Library;
 | 
					 | 
				
			||||||
        public FTFace Face => Ptr->Face;
 | 
					 | 
				
			||||||
        public FTGlyphSlot Next => Ptr->Next;
 | 
					 | 
				
			||||||
        public uint GlyphIndex => Ptr->GlyphIndex;
 | 
					 | 
				
			||||||
        public ref readonly FTGlyphMetrics Metrics => ref Ptr->Metrics;
 | 
					 | 
				
			||||||
        public long LinearHorizontalAdvance => Ptr->LinearHorizontalAdvance;
 | 
					 | 
				
			||||||
        public long LinearVerticalAdvance => Ptr->LinearVerticalAdvance;
 | 
					 | 
				
			||||||
        public FTVector Advance => Ptr->Advance;
 | 
					 | 
				
			||||||
        public ref readonly FTBitmap Bitmap => ref Ptr->Bitmap;
 | 
					 | 
				
			||||||
        public long BitmapLeft => Ptr->BitmapLeft;
 | 
					 | 
				
			||||||
        public long BitmapTop => Ptr->BitmapTop;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public struct FTGlyphMetrics
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public long Width;
 | 
					 | 
				
			||||||
        public long Height;
 | 
					 | 
				
			||||||
        public long HorizontalBearingX;
 | 
					 | 
				
			||||||
        public long HorizontalBearingY;
 | 
					 | 
				
			||||||
        public long HorizontalAdvance;
 | 
					 | 
				
			||||||
        public long VerticalBearingX;
 | 
					 | 
				
			||||||
        public long VerticalBearingY;
 | 
					 | 
				
			||||||
        public long VerticalAdvance;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public struct FTSizeMetrics
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public short Xppem;
 | 
					 | 
				
			||||||
        public short Yppem;
 | 
					 | 
				
			||||||
        public long XScale;
 | 
					 | 
				
			||||||
        public long YScale;
 | 
					 | 
				
			||||||
        public long Ascender;
 | 
					 | 
				
			||||||
        public long Descender;
 | 
					 | 
				
			||||||
        public long Height;
 | 
					 | 
				
			||||||
        public long MaxAdvance;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public struct FTSize
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public IntPtr Face;
 | 
					 | 
				
			||||||
        public FTGeneric Generic;
 | 
					 | 
				
			||||||
        public FTSizeMetrics Metrics;
 | 
					 | 
				
			||||||
        private IntPtr Privates;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										30
									
								
								Quik.sln
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								Quik.sln
									
									
									
									
									
								
							@ -1,14 +1,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Microsoft Visual Studio Solution File, Format Version 12.00
 | 
					Microsoft Visual Studio Solution File, Format Version 12.00
 | 
				
			||||||
#
 | 
					# 
 | 
				
			||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quik", "Quik\Quik.csproj", "{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}"
 | 
					Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quik", "Quik\Quik.csproj", "{B86B2B99-DAE4-43CE-A040-1D8E143B94A7}"
 | 
				
			||||||
EndProject
 | 
					EndProject
 | 
				
			||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quik.OpenTK", "Quik.OpenTK\Quik.OpenTK.csproj", "{586E5E28-1D07-4CC2-B04F-0BC420564F57}"
 | 
					Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quik.OpenTK", "Quik.OpenTK\Quik.OpenTK.csproj", "{586E5E28-1D07-4CC2-B04F-0BC420564F57}"
 | 
				
			||||||
EndProject
 | 
					EndProject
 | 
				
			||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QuikTestApplication", "QuikTestApplication\QuikTestApplication.csproj", "{49AEF502-692A-48A4-8076-EF2228925280}"
 | 
					 | 
				
			||||||
EndProject
 | 
					 | 
				
			||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Quik.FreeType", "Quik.FreeType\Quik.FreeType.csproj", "{53B95098-F304-47E6-A08C-DAFA589F5BCF}"
 | 
					 | 
				
			||||||
EndProject
 | 
					 | 
				
			||||||
Global
 | 
					Global
 | 
				
			||||||
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
						GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
				
			||||||
		Debug|Any CPU = Debug|Any CPU
 | 
							Debug|Any CPU = Debug|Any CPU
 | 
				
			||||||
@ -43,29 +39,5 @@ Global
 | 
				
			|||||||
		{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x64.Build.0 = Release|Any CPU
 | 
							{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x64.Build.0 = Release|Any CPU
 | 
				
			||||||
		{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x86.ActiveCfg = Release|Any CPU
 | 
							{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x86.ActiveCfg = Release|Any CPU
 | 
				
			||||||
		{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x86.Build.0 = Release|Any CPU
 | 
							{586E5E28-1D07-4CC2-B04F-0BC420564F57}.Release|x86.Build.0 = Release|Any CPU
 | 
				
			||||||
		{49AEF502-692A-48A4-8076-EF2228925280}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
					 | 
				
			||||||
		{49AEF502-692A-48A4-8076-EF2228925280}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
					 | 
				
			||||||
		{49AEF502-692A-48A4-8076-EF2228925280}.Debug|x64.ActiveCfg = Debug|Any CPU
 | 
					 | 
				
			||||||
		{49AEF502-692A-48A4-8076-EF2228925280}.Debug|x64.Build.0 = Debug|Any CPU
 | 
					 | 
				
			||||||
		{49AEF502-692A-48A4-8076-EF2228925280}.Debug|x86.ActiveCfg = Debug|Any CPU
 | 
					 | 
				
			||||||
		{49AEF502-692A-48A4-8076-EF2228925280}.Debug|x86.Build.0 = Debug|Any CPU
 | 
					 | 
				
			||||||
		{49AEF502-692A-48A4-8076-EF2228925280}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
					 | 
				
			||||||
		{49AEF502-692A-48A4-8076-EF2228925280}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
					 | 
				
			||||||
		{49AEF502-692A-48A4-8076-EF2228925280}.Release|x64.ActiveCfg = Release|Any CPU
 | 
					 | 
				
			||||||
		{49AEF502-692A-48A4-8076-EF2228925280}.Release|x64.Build.0 = Release|Any CPU
 | 
					 | 
				
			||||||
		{49AEF502-692A-48A4-8076-EF2228925280}.Release|x86.ActiveCfg = Release|Any CPU
 | 
					 | 
				
			||||||
		{49AEF502-692A-48A4-8076-EF2228925280}.Release|x86.Build.0 = Release|Any CPU
 | 
					 | 
				
			||||||
		{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
					 | 
				
			||||||
		{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
					 | 
				
			||||||
		{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Debug|x64.ActiveCfg = Debug|Any CPU
 | 
					 | 
				
			||||||
		{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Debug|x64.Build.0 = Debug|Any CPU
 | 
					 | 
				
			||||||
		{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Debug|x86.ActiveCfg = Debug|Any CPU
 | 
					 | 
				
			||||||
		{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Debug|x86.Build.0 = Debug|Any CPU
 | 
					 | 
				
			||||||
		{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
					 | 
				
			||||||
		{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
					 | 
				
			||||||
		{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Release|x64.ActiveCfg = Release|Any CPU
 | 
					 | 
				
			||||||
		{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Release|x64.Build.0 = Release|Any CPU
 | 
					 | 
				
			||||||
		{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Release|x86.ActiveCfg = Release|Any CPU
 | 
					 | 
				
			||||||
		{53B95098-F304-47E6-A08C-DAFA589F5BCF}.Release|x86.Build.0 = Release|Any CPU
 | 
					 | 
				
			||||||
	EndGlobalSection
 | 
						EndGlobalSection
 | 
				
			||||||
EndGlobal
 | 
					EndGlobal
 | 
				
			||||||
 | 
				
			|||||||
@ -1,183 +0,0 @@
 | 
				
			|||||||
using System;
 | 
					 | 
				
			||||||
using System.Collections.Generic;
 | 
					 | 
				
			||||||
using System.Diagnostics;
 | 
					 | 
				
			||||||
using Quik;
 | 
					 | 
				
			||||||
using Quik.VertexGenerator;
 | 
					 | 
				
			||||||
using OpenTK.Mathematics;
 | 
					 | 
				
			||||||
using OpenTK.Graphics.OpenGL4;
 | 
					 | 
				
			||||||
using OpenTK.Windowing.Common;
 | 
					 | 
				
			||||||
using OpenTK.Windowing.Desktop;
 | 
					 | 
				
			||||||
using OpenTK.Windowing.GraphicsLibraryFramework;
 | 
					 | 
				
			||||||
using Quik.FreeType;
 | 
					 | 
				
			||||||
using Quik.OpenTK;
 | 
					 | 
				
			||||||
using Quik.Typography;
 | 
					 | 
				
			||||||
using Quik.Controls;
 | 
					 | 
				
			||||||
using Quik.OpenGL;
 | 
					 | 
				
			||||||
using GL = Quik.OpenGL.GL;
 | 
					 | 
				
			||||||
using static Quik.OpenGL.GLEnum;
 | 
					 | 
				
			||||||
using Quik.CommandMachine;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace QuikTestApplication
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public class Program
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public const string vertex =
 | 
					 | 
				
			||||||
            @"#version 140
 | 
					 | 
				
			||||||
uniform mat4 matrix;
 | 
					 | 
				
			||||||
in vec2 position;
 | 
					 | 
				
			||||||
in vec2 texcoord;
 | 
					 | 
				
			||||||
in vec4 color;
 | 
					 | 
				
			||||||
out vec2 ftexcoord;
 | 
					 | 
				
			||||||
out vec4 fcolor;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void main()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    fcolor = color;
 | 
					 | 
				
			||||||
    ftexcoord = texcoord;
 | 
					 | 
				
			||||||
    gl_Position = matrix * vec4(position.xy, 0, 1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public const string fragment =
 | 
					 | 
				
			||||||
            @"#version 140
 | 
					 | 
				
			||||||
in vec2 ftexcoord;
 | 
					 | 
				
			||||||
in vec4 fcolor;
 | 
					 | 
				
			||||||
out vec4 outcolor;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
uniform sampler2D texture0;
 | 
					 | 
				
			||||||
uniform vec2 texture0offset;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void main()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    outcolor = fcolor * texture(texture0, ftexcoord + texture0offset);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static void Main(string[] args)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            NativeWindowSettings windowSettings = NativeWindowSettings.Default;
 | 
					 | 
				
			||||||
            windowSettings.NumberOfSamples = 4;
 | 
					 | 
				
			||||||
            NativeWindow window = new NativeWindow(windowSettings);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            window.Context.MakeCurrent();
 | 
					 | 
				
			||||||
            GL.LoadBindings(new GLFWBindingsContext().GetProcAddress);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            FreeTypeFontManager fontManager = new FreeTypeFontManager();
 | 
					 | 
				
			||||||
            QuikContext           context = new QuikContext(new OpenGLTextureManager(), fontManager);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            VertexGeneratorEngine engine    = new VertexGeneratorEngine();
 | 
					 | 
				
			||||||
            CommandQueue          cmdQueue  = new CommandQueue();
 | 
					 | 
				
			||||||
            GL30Driver            gldriver;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            RootControl root = new RootControl(context);
 | 
					 | 
				
			||||||
            Button button = new Button()
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                Bounds = new QRectangle(120, 60, 20, 20),
 | 
					 | 
				
			||||||
                Text = "button",
 | 
					 | 
				
			||||||
                Padding = 8,
 | 
					 | 
				
			||||||
                NormalStroke = new QuikStrokeStyle(new QColor(0xccccccff), 4f),
 | 
					 | 
				
			||||||
                HoverStroke = new QuikStrokeStyle(new QColor(0x1010ccff), 4f),
 | 
					 | 
				
			||||||
                ActiveStroke = new QuikStrokeStyle(new QColor(0x999999ff), 4f),
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            button.Clicked += (sender, args) => {
 | 
					 | 
				
			||||||
                if (!args.Buttons.HasFlag(Quik.MouseButton.Primary))
 | 
					 | 
				
			||||||
                    return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                Button xbutton = (Button)sender;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (xbutton.Text == "button")
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    xbutton.Text = "le button";
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    xbutton.Text = "button";
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            root.MouseEnter += (_,_) => Console.WriteLine("enter");
 | 
					 | 
				
			||||||
            root.MouseLeave += (_,_) => Console.WriteLine("leave");
 | 
					 | 
				
			||||||
            root.MouseMove  += (_,_) => Console.WriteLine("move");
 | 
					 | 
				
			||||||
            root.MouseDown  += (_,_) => Console.WriteLine("down");
 | 
					 | 
				
			||||||
            root.MouseUp    += (_,_) => Console.WriteLine("up");
 | 
					 | 
				
			||||||
            root.Add(button);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            GL.Enable(GL_MULTISAMPLE);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            gldriver = new GL30Driver();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            window.Context.SwapInterval = 0;
 | 
					 | 
				
			||||||
            Stopwatch stopwatch = Stopwatch.StartNew();
 | 
					 | 
				
			||||||
            float lastMs = stopwatch.ElapsedMilliseconds;
 | 
					 | 
				
			||||||
            int frames = 0;
 | 
					 | 
				
			||||||
            for (;!window.IsExiting;)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                NativeWindow.ProcessWindowEvents(false);
 | 
					 | 
				
			||||||
                window.ProcessEvents(0.0f);
 | 
					 | 
				
			||||||
                window.TryGetCurrentMonitorDpi(out float dpi, out _);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (window.IsFocused)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    var mouseState = window.MouseState;
 | 
					 | 
				
			||||||
                    QVec2 postion = new QVec2(mouseState.Position.X, window.ClientSize.Y - mouseState.Position.Y) * (dpi/72f);
 | 
					 | 
				
			||||||
                    Quik.MouseButton buttons =
 | 
					 | 
				
			||||||
                        (mouseState.IsButtonDown(OpenTK.Windowing.GraphicsLibraryFramework.MouseButton.Button1) ? Quik.MouseButton.Primary : 0) |
 | 
					 | 
				
			||||||
                        (mouseState.IsButtonDown(OpenTK.Windowing.GraphicsLibraryFramework.MouseButton.Button2) ? Quik.MouseButton.Secondary : 0) |
 | 
					 | 
				
			||||||
                        (mouseState.IsButtonDown(OpenTK.Windowing.GraphicsLibraryFramework.MouseButton.Button3) ? Quik.MouseButton.Tertiary : 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    root.NotifyMouse(new Quik.MouseState(postion, buttons));
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                root.Bounds = new QRectangle(
 | 
					 | 
				
			||||||
                    window.ClientSize.X,
 | 
					 | 
				
			||||||
                    window.ClientSize.Y,
 | 
					 | 
				
			||||||
                    0,
 | 
					 | 
				
			||||||
                    0);
 | 
					 | 
				
			||||||
                root.NotifyUpdate();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                cmdQueue.Clear();
 | 
					 | 
				
			||||||
                root.NotifyPaint(cmdQueue);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                engine.Reset();
 | 
					 | 
				
			||||||
                engine.ProcessCommands(root.Bounds, cmdQueue);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                DrawQueue drawQueue = engine.DrawQueue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                GL.Clear(GL_COLOR_BUFFER_BIT);
 | 
					 | 
				
			||||||
                gldriver.Draw(drawQueue);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                window.Context.SwapBuffers();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                frames++;
 | 
					 | 
				
			||||||
                float ms = stopwatch.ElapsedMilliseconds; 
 | 
					 | 
				
			||||||
                if (ms - lastMs > 1000)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    Console.WriteLine("Frames: {0}", frames*(ms - lastMs)/1000);
 | 
					 | 
				
			||||||
                    frames = 0;
 | 
					 | 
				
			||||||
                    lastMs = ms;
 | 
					 | 
				
			||||||
                    Console.WriteLine("Vertex Usage: {0} ; Element Usage: {1} Calls: {2}", drawQueue.VertexCount, drawQueue.ElementCount, drawQueue.DrawCallCount);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public class TextFontManager : IQuikFontManager
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            public QuikContext Context { get; set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            private TestFont _font;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            public void Clear()
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            public QuikFont GetFont(QuikFontStyle fontStyle)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (_font is null)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    _font = new TestFont(Context);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                return _font;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,21 +0,0 @@
 | 
				
			|||||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <PropertyGroup>
 | 
					 | 
				
			||||||
        <OutputType>Exe</OutputType>
 | 
					 | 
				
			||||||
        <TargetFramework>net6.0</TargetFramework>
 | 
					 | 
				
			||||||
        <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
 | 
					 | 
				
			||||||
    </PropertyGroup>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <ItemGroup>
 | 
					 | 
				
			||||||
      <ProjectReference Include="..\Quik.FreeType\Quik.FreeType.csproj" />
 | 
					 | 
				
			||||||
      <ProjectReference Include="..\Quik.OpenTK\Quik.OpenTK.csproj" />
 | 
					 | 
				
			||||||
    </ItemGroup>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <ItemGroup>
 | 
					 | 
				
			||||||
      <None Remove="font.dat" />
 | 
					 | 
				
			||||||
      <EmbeddedResource Include="font.dat" />
 | 
					 | 
				
			||||||
      <None Remove="font.xml" />
 | 
					 | 
				
			||||||
      <EmbeddedResource Include="font.xml" />
 | 
					 | 
				
			||||||
    </ItemGroup>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</Project>
 | 
					 | 
				
			||||||
@ -1,126 +0,0 @@
 | 
				
			|||||||
using System;
 | 
					 | 
				
			||||||
using System.Collections.Generic;
 | 
					 | 
				
			||||||
using System.IO;
 | 
					 | 
				
			||||||
using System.Runtime.CompilerServices;
 | 
					 | 
				
			||||||
using System.Runtime.InteropServices;
 | 
					 | 
				
			||||||
using System.Xml;
 | 
					 | 
				
			||||||
using Quik;
 | 
					 | 
				
			||||||
using Quik.Typography;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace QuikTestApplication
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public class TestFont : QuikFont
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        public override QuikFontStyle Style => _style;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private static QuikFontStyle _style;
 | 
					 | 
				
			||||||
        private static HashSet<int> _characters = new HashSet<int>();
 | 
					 | 
				
			||||||
        private static Dictionary<int, QuikGlyph> _glyphs = new Dictionary<int, QuikGlyph>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public static byte[] TextureData { get; private set; } = Array.Empty<byte>();
 | 
					 | 
				
			||||||
        public static QVec2 TextureSize { get; private set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public QuikTexture Texture { get; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public override float Ascender => throw new NotImplementedException();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public override float Descender => throw new NotImplementedException();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public TestFont(QuikContext context)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            Texture = context.TextureManager.CreateTexture(TextureSize, false, QuikImageFormat.RgbaU8);
 | 
					 | 
				
			||||||
            unsafe
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                fixed (byte* ptr = &TextureData[0])
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    Texture.Image((IntPtr)ptr, QuikImageFormat.RgbaU8, TextureSize, 0);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        static TestFont()
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            using (Stream str = typeof(TestFont).Assembly.GetManifestResourceStream("QuikTestApplication.font.xml"))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                XmlDocument document = new XmlDocument();
 | 
					 | 
				
			||||||
                document.Load(str);
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                string family = document.DocumentElement.Attributes["name"].Value;
 | 
					 | 
				
			||||||
                float fontSize = float.Parse(document.DocumentElement.Attributes["size"].Value);
 | 
					 | 
				
			||||||
                QuikFontType style = QuikFontType.Normal;
 | 
					 | 
				
			||||||
                if (document.DocumentElement.Attributes["bold"].Value == "true")
 | 
					 | 
				
			||||||
                    style = QuikFontType.Bold;
 | 
					 | 
				
			||||||
                if (document.DocumentElement.Attributes["italic"].Value == "true")
 | 
					 | 
				
			||||||
                    style = QuikFontType.Italic;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                _style = new QuikFontStyle(family, fontSize, style);
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                QVec2 atlasSize = default;
 | 
					 | 
				
			||||||
                atlasSize.X = float.Parse(document.DocumentElement.Attributes["width"].Value);
 | 
					 | 
				
			||||||
                atlasSize.Y = float.Parse(document.DocumentElement.Attributes["height"].Value);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                TextureSize = atlasSize;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                foreach (XmlElement element in document.SelectNodes("/font/character"))
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    QRectangle UVs;
 | 
					 | 
				
			||||||
                    QVec2 origin;
 | 
					 | 
				
			||||||
                    float advance;
 | 
					 | 
				
			||||||
                    int chr = element.Attributes["text"].Value[0];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    QVec2 pos;
 | 
					 | 
				
			||||||
                    QVec2 size;
 | 
					 | 
				
			||||||
                    pos.X = float.Parse(element.Attributes["x"].Value);
 | 
					 | 
				
			||||||
                    pos.Y = float.Parse(element.Attributes["y"].Value);
 | 
					 | 
				
			||||||
                    size.X = float.Parse(element.Attributes["width"].Value);
 | 
					 | 
				
			||||||
                    size.Y = float.Parse(element.Attributes["height"].Value);
 | 
					 | 
				
			||||||
                    UVs = new QRectangle(
 | 
					 | 
				
			||||||
                        (pos.X + size.X)/atlasSize.X, 
 | 
					 | 
				
			||||||
                        pos.Y/atlasSize.Y,
 | 
					 | 
				
			||||||
                        pos.X/atlasSize.X,
 | 
					 | 
				
			||||||
                        (size.Y + pos.Y)/atlasSize.Y);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    origin.X = float.Parse(element.Attributes["origin-x"].Value);
 | 
					 | 
				
			||||||
                    origin.Y = float.Parse(element.Attributes["origin-y"].Value);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    advance = float.Parse(element.Attributes["advance"].Value);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    QuikGlyph glyph = new QuikGlyph(chr, UVs, size, origin, default, new QVec2(advance, 0));
 | 
					 | 
				
			||||||
                    _glyphs.Add(chr, glyph);
 | 
					 | 
				
			||||||
                    _characters.Add(chr);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            using (Stream str = typeof(TestFont).Assembly.GetManifestResourceStream("QuikTestApplication.font.dat"))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                TextureData = new byte[(int)str.Length];
 | 
					 | 
				
			||||||
                str.Read(TextureData, 0, (int)str.Length);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            // Evil pointer stuff. Beware!
 | 
					 | 
				
			||||||
            Span<uint> head = MemoryMarshal.Cast<byte, uint>(TextureData);
 | 
					 | 
				
			||||||
            for (int i = 0; i < head.Length; i++)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (head[i] == 0xff000000)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    head[i] = 0x00000000;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public override bool HasCharacter(int character)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return _characters.Contains((char) character);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public override void GetCharacter(int character, out QuikTexture texture, out QuikGlyph glyph)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (!_glyphs.TryGetValue(character, out glyph))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                glyph = _glyphs['?'];
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            texture = Texture;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 24 KiB  | 
@ -1,98 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="utf-8"?>
 | 
					 | 
				
			||||||
<font name="monospace" bold="false" italic="false" width="512" height="128" size="32">
 | 
					 | 
				
			||||||
    <character text=" " x="69" y="84" width="3" height="3" origin-x="1" origin-y="1" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="!" x="116" y="59" width="6" height="25" origin-x="-7" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text=""" x="487" y="59" width="11" height="11" origin-x="-4" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="#" x="373" y="0" width="22" height="25" origin-x="1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="$" x="48" y="0" width="18" height="31" origin-x="-1" origin-y="25" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="%" x="417" y="0" width="21" height="25" origin-x="1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="&" x="438" y="0" width="21" height="25" origin-x="1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="'" x="498" y="59" width="5" height="11" origin-x="-7" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="(" x="66" y="0" width="10" height="31" origin-x="-5" origin-y="25" advance="19"/>
 | 
					 | 
				
			||||||
    <character text=")" x="76" y="0" width="10" height="31" origin-x="-4" origin-y="25" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="*" x="423" y="59" width="17" height="17" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="+" x="359" y="59" width="19" height="19" origin-x="0" origin-y="20" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="," x="440" y="59" width="8" height="12" origin-x="-5" origin-y="7" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="-" x="58" y="84" width="11" height="5" origin-x="-4" origin-y="12" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="." x="29" y="84" width="7" height="7" origin-x="-6" origin-y="6" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="/" x="145" y="0" width="18" height="29" origin-x="0" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="0" x="198" y="34" width="18" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="1" x="360" y="34" width="17" height="25" origin-x="-2" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="2" x="377" y="34" width="17" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="3" x="394" y="34" width="17" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="4" x="103" y="34" width="19" height="25" origin-x="0" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="5" x="411" y="34" width="17" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="6" x="216" y="34" width="18" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="7" x="428" y="34" width="17" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="8" x="234" y="34" width="18" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="9" x="252" y="34" width="18" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text=":" x="378" y="59" width="7" height="19" origin-x="-6" origin-y="18" advance="19"/>
 | 
					 | 
				
			||||||
    <character text=";" x="122" y="59" width="8" height="23" origin-x="-5" origin-y="18" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="<" x="385" y="59" width="19" height="18" origin-x="0" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="=" x="468" y="59" width="19" height="11" origin-x="0" origin-y="16" advance="19"/>
 | 
					 | 
				
			||||||
    <character text=">" x="404" y="59" width="19" height="18" origin-x="0" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="?" x="68" y="59" width="16" height="25" origin-x="-2" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="@" x="105" y="0" width="21" height="29" origin-x="1" origin-y="23" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="A" x="459" y="0" width="21" height="25" origin-x="1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="B" x="270" y="34" width="18" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="C" x="445" y="34" width="17" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="D" x="288" y="34" width="18" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="E" x="462" y="34" width="17" height="25" origin-x="-2" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="F" x="479" y="34" width="17" height="25" origin-x="-2" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="G" x="122" y="34" width="19" height="25" origin-x="0" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="H" x="306" y="34" width="18" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="I" x="84" y="59" width="16" height="25" origin-x="-2" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="J" x="100" y="59" width="16" height="25" origin-x="0" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="K" x="63" y="34" width="20" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="L" x="0" y="59" width="17" height="25" origin-x="-2" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="M" x="141" y="34" width="19" height="25" origin-x="0" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="N" x="324" y="34" width="18" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="O" x="160" y="34" width="19" height="25" origin-x="0" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="P" x="17" y="59" width="17" height="25" origin-x="-2" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="Q" x="126" y="0" width="19" height="29" origin-x="0" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="R" x="83" y="34" width="20" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="S" x="342" y="34" width="18" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="T" x="480" y="0" width="21" height="25" origin-x="1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="U" x="34" y="59" width="17" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="V" x="0" y="34" width="21" height="25" origin-x="1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="W" x="395" y="0" width="22" height="25" origin-x="1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="X" x="21" y="34" width="21" height="25" origin-x="1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="Y" x="42" y="34" width="21" height="25" origin-x="1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="Z" x="179" y="34" width="19" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="[" x="96" y="0" width="9" height="31" origin-x="-6" origin-y="25" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="\" x="163" y="0" width="18" height="29" origin-x="0" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="]" x="86" y="0" width="10" height="31" origin-x="-4" origin-y="25" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="^" x="448" y="59" width="20" height="11" origin-x="0" origin-y="25" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="_" x="36" y="84" width="22" height="5" origin-x="1" origin-y="-4" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="`" x="0" y="84" width="10" height="8" origin-x="-3" origin-y="27" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="a" x="246" y="59" width="17" height="20" origin-x="-1" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="b" x="307" y="0" width="17" height="26" origin-x="-2" origin-y="25" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="c" x="263" y="59" width="16" height="20" origin-x="-2" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="d" x="253" y="0" width="18" height="26" origin-x="0" origin-y="25" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="e" x="152" y="59" width="19" height="20" origin-x="0" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="f" x="341" y="0" width="16" height="26" origin-x="-2" origin-y="25" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="g" x="200" y="0" width="18" height="27" origin-x="0" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="h" x="357" y="0" width="16" height="26" origin-x="-2" origin-y="25" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="i" x="271" y="0" width="18" height="26" origin-x="-1" origin-y="25" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="j" x="5" y="0" width="13" height="33" origin-x="-1" origin-y="25" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="k" x="289" y="0" width="18" height="26" origin-x="-2" origin-y="25" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="l" x="324" y="0" width="17" height="26" origin-x="-1" origin-y="25" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="m" x="171" y="59" width="19" height="20" origin-x="0" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="n" x="279" y="59" width="16" height="20" origin-x="-2" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="o" x="228" y="59" width="18" height="20" origin-x="-1" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="p" x="218" y="0" width="18" height="27" origin-x="-1" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="q" x="236" y="0" width="17" height="27" origin-x="-1" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="r" x="295" y="59" width="16" height="20" origin-x="-4" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="s" x="311" y="59" width="16" height="20" origin-x="-2" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="t" x="51" y="59" width="17" height="25" origin-x="-1" origin-y="24" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="u" x="327" y="59" width="16" height="20" origin-x="-2" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="v" x="190" y="59" width="19" height="20" origin-x="0" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="w" x="130" y="59" width="22" height="20" origin-x="1" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="x" x="209" y="59" width="19" height="20" origin-x="0" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="y" x="181" y="0" width="19" height="27" origin-x="0" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="z" x="343" y="59" width="16" height="20" origin-x="-2" origin-y="19" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="{" x="18" y="0" width="15" height="32" origin-x="-2" origin-y="25" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="|" x="0" y="0" width="5" height="34" origin-x="-7" origin-y="25" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="}" x="33" y="0" width="15" height="32" origin-x="-2" origin-y="25" advance="19"/>
 | 
					 | 
				
			||||||
    <character text="~" x="10" y="84" width="19" height="7" origin-x="0" origin-y="14" advance="19"/>
 | 
					 | 
				
			||||||
</font>
 | 
					 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user