<commit_before>﻿using OpenTK;
using OpenTK.Graphics;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.IO;
using System.Threading;

namespace StorybrewCommon.Subtitles
{
    public class FontTexture
    {
        private string path;
        public string Path => path;
        public bool IsEmpty => path == null;

        private int baseWidth;
        public int BaseWidth => baseWidth;

        private int baseHeight;
        public int BaseHeight => baseHeight;

        private int width;
        public int Width => width;

        private int height;
        public int Height => height;

        public FontTexture(string path, int baseWidth, int baseHeight, int width, int height)
        {
            this.path = path;
            this.baseWidth = baseWidth;
            this.baseHeight = baseHeight;
            this.width = width;
            this.height = height;
        }
    }

    public class FontDescription
    {
        public string FontPath;
        public int FontSize = 76;
        public Color4 Color = new Color4(0, 0, 0, 100);
        public Vector2 Padding = Vector2.Zero;
        public bool Debug;
    }

    public class FontGenerator
    {
        private FontDescription description;
        private FontEffect[] effects;
        private string projectDirectory;
        private string mapsetDirectory;
        private string directory;

        private Dictionary<string, FontTexture> letters = new Dictionary<string, FontTexture>();

        public FontGenerator(string directory, FontDescription description, FontEffect[] effects, string projectDirectory, string mapsetDirectory)
        {
            this.description = description;
            this.effects = effects;
            this.projectDirectory = projectDirectory;
            this.mapsetDirectory = mapsetDirectory;
            this.directory = directory;
        }

        public FontTexture GetTexture(string text)
        {
            FontTexture texture;
            if (!letters.TryGetValue(text, out texture))
                letters.Add(text, texture = generateTexture(text));
            return texture;
        }

        private FontTexture generateTexture(string text)
        {
            var filename = text.Length == 1 ? $"{(int)text[0]:x4}.png" : $"_{letters.Count:x3}.png";
            var bitmapPath = Path.Combine(mapsetDirectory, directory, filename);

            Directory.CreateDirectory(Path.GetDirectoryName(bitmapPath));

            var fontPath = Path.Combine(projectDirectory, description.FontPath);
            if (!File.Exists(fontPath)) fontPath = description.FontPath;

            int baseWidth, baseHeight, width, height;
            using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero))
            using (StringFormat stringFormat = new StringFormat(StringFormat.GenericTypographic))
            using (var textBrush = new SolidBrush(Color.FromArgb(description.Color.ToArgb())))
            using (var fontCollection = new PrivateFontCollection())
            {
                graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
                stringFormat.Alignment = StringAlignment.Center;
                stringFormat.FormatFlags = StringFormatFlags.FitBlackBox | StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoClip;

                fontCollection.AddFontFile(fontPath);
                var fontFamily = fontCollection.Families[0];

                var fontStyle = FontStyle.Regular;
                using (var font = new Font(fontFamily, description.FontSize, fontStyle))
                {<commit_msg>Add support for system fonts.<commit_after>﻿using OpenTK;
using OpenTK.Graphics;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.IO;
using System.Threading;

namespace StorybrewCommon.Subtitles
{
    public class FontTexture
    {
        private string path;
        public string Path => path;
        public bool IsEmpty => path == null;

        private int baseWidth;
        public int BaseWidth => baseWidth;

        private int baseHeight;
        public int BaseHeight => baseHeight;

        private int width;
        public int Width => width;

        private int height;
        public int Height => height;

        public FontTexture(string path, int baseWidth, int baseHeight, int width, int height)
        {
            this.path = path;
            this.baseWidth = baseWidth;
            this.baseHeight = baseHeight;
            this.width = width;
            this.height = height;
        }
    }

    public class FontDescription
    {
        public string FontPath;
        public int FontSize = 76;
        public Color4 Color = new Color4(0, 0, 0, 100);
        public Vector2 Padding = Vector2.Zero;
        public bool Debug;
    }

    public class FontGenerator
    {
        private FontDescription description;
        private FontEffect[] effects;
        private string projectDirectory;
        private string mapsetDirectory;
        private string directory;

        private Dictionary<string, FontTexture> letters = new Dictionary<string, FontTexture>();

        public FontGenerator(string directory, FontDescription description, FontEffect[] effects, string projectDirectory, string mapsetDirectory)
        {
            this.description = description;
            this.effects = effects;
            this.projectDirectory = projectDirectory;
            this.mapsetDirectory = mapsetDirectory;
            this.directory = directory;
        }

        public FontTexture GetTexture(string text)
        {
            FontTexture texture;
            if (!letters.TryGetValue(text, out texture))
                letters.Add(text, texture = generateTexture(text));
            return texture;
        }

        private FontTexture generateTexture(string text)
        {
            var filename = text.Length == 1 ? $"{(int)text[0]:x4}.png" : $"_{letters.Count:x3}.png";
            var bitmapPath = Path.Combine(mapsetDirectory, directory, filename);

            Directory.CreateDirectory(Path.GetDirectoryName(bitmapPath));

            var fontPath = Path.Combine(projectDirectory, description.FontPath);
            if (!File.Exists(fontPath)) fontPath = description.FontPath;

            int baseWidth, baseHeight, width, height;
            using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero))
            using (StringFormat stringFormat = new StringFormat(StringFormat.GenericTypographic))
            using (var textBrush = new SolidBrush(Color.FromArgb(description.Color.ToArgb())))
            using (var fontCollection = new PrivateFontCollection())
            {
                graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
                stringFormat.Alignment = StringAlignment.Center;
                stringFormat.FormatFlags = StringFormatFlags.FitBlackBox | StringFormatFlags.MeasureTrailingSpaces | StringFormatFlags.NoClip;

                FontFamily fontFamily = null;
                if (File.Exists(fontPath))
                {
                    fontCollection.AddFontFile(fontPath);
                    fontFamily = fontCollection.Families[0];
                }

                var fontStyle = FontStyle.Regular;
                using (var font = fontFamily != null ? new Font(fontFamily, description.FontSize, fontStyle) : new Font(fontPath, description.FontSize, fontStyle))
                {
{'fraction_non_alphanumeric': 0.07842879663688912, 'fraction_numerical': 0.004729374671571204, 'mean_word_length': 2.3244541484716157, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2210429', 'n_tokens_mistral': 1893, 'n_tokens_neox': 1797, 'n_words': 498}