reckfellENGINE

Шрифты: загрузка, размер, перенос и fallback

Полный пример C#: встроенный шрифт, FontFile, SystemFont и FontVariation; настройки качества и экспорта.

На этой странице

Запустить пример без внешнего файла

Добавьте UiSampleStyle.cs и FontsDemo.cs в C#-проект. Прикрепите FontsDemo к корню Control отдельного уровня, соберите и запустите F6.

Две надписи показывают латиницу, кириллицу и комбинируемый акцент. У них разные размеры; большая использует FontVariation с синтетическим утолщением. Длинная нижняя надпись переносится при сужении окна. Многоязычная строка специально одинакова в обеих версиях примера.

FontsDemo.cs
C#
using Reckfell;

public partial class FontsDemo : Control
{
    public Label Small { get; private set; } = null!;
    public Label Large { get; private set; } = null!;
    public FontVariation Bold { get; private set; } = null!;
    public Label Wrapped { get; private set; } = null!;
    public override void _Ready()
    {
        UiSampleStyle.Prepare(this);
        var margin = new MarginContainer(); AddChild(margin); margin.SetAnchorsAndOffsetsPreset(LayoutPreset.FullRect, margin: 24);
        var column = new VBoxContainer(); margin.AddChild(column);
        Small = new Label { Text = "Reckfell — Привет!  Cafe\u0301", AutowrapMode = TextServer.AutowrapMode.WordSmart };
        Large = new Label { Text = Small.Text, AutowrapMode = TextServer.AutowrapMode.WordSmart };
        column.AddChild(Small); column.AddChild(Large);
        Small.AddThemeFontSizeOverride("font_size", 16); Large.AddThemeFontSizeOverride("font_size", 28);
        Wrapped = new Label
        {
            Text = UiSampleStyle.Text("Длинная надпись переносится в пределах доступной ширины. Размер шрифта задаётся отдельно от файла.", "A longer label wraps within the available width. Font size is configured separately from the font file."),
            AutowrapMode = TextServer.AutowrapMode.WordSmart
        };
        column.AddChild(Wrapped); SetFont(Small.GetThemeFont("font"));
    }
    private void SetFont(Font font)
    {
        Theme.DefaultFont = font;
        Bold = new FontVariation { BaseFont = font, VariationEmbolden = 1.2f };
        Large.AddThemeFontOverride("font", Bold);
    }
    public Error LoadProjectFont(string path)
    {
        if (!path.StartsWith("asset://") || !FileAccess.FileExists(path)) return Error.FileNotFound;
        var font = ResourceLoader.Load<FontFile>(path);
        if (font is null) return Error.FileUnrecognized;
        SetFont(font); return Error.Ok;
    }
    public Error LoadExternalFont(string path)
    {
        const ulong maxBytes = 16UL * 1024 * 1024;
        if (!FileAccess.FileExists(path)) return Error.FileNotFound;
        byte[] data;
        using (var file = FileAccess.Open(path, FileAccess.ModeFlags.Read))
        {
            if (file is null) return FileAccess.GetOpenError();
            ulong length = file.GetLength();
            if (length == 0 || length > maxBytes) return Error.InvalidData;
            data = file.GetBuffer((long)length);
            if ((ulong)data.LongLength != length) return Error.InvalidData;
        }
        var font = new FontFile(); font.SetData(data);
        SetFont(font); return Error.Ok;
    }
    public void UseSystemFont(string[] names) => SetFont(new SystemFont { FontNames = names });
}

Загрузить свой шрифт

ИсточникДействие
Шрифт проектаДобавьте TTF/OTF в проект, дождитесь импорта, вызовите LoadProjectFont с asset://путём
Внешний динамический файл во время работыLoadExternalFont ограничивает чтение 16 МиБ, проверяет число байтов и назначает их через FontFile.SetData
Семейство, установленное в ОСUseSystemFont с массивом имён; наличие и результат различаются на устройствах
Bitmap-шрифтИмпорт BMFont .fnt или импорт изображения шрифта; настройте сетку/набор символов под источник

Размер задаётся у Control через Theme Overrides → Font Sizes или Theme.SetFontSize, а не отдельной копией TTF на каждый размер. Поля Fonts и Default Font выбирают ресурс. В этой сборке встроенный резервный шрифт — Open Sans SemiBold; проектная тема/шрифт могут его заменить. Для воспроизводимого экспорта добавляйте нужные файлы и fallback-ресурсы в проект: SystemFont не упаковывает установленные шрифты ОС в игру.

Внешний загрузчик выше отклоняет отсутствующий, пустой, слишком большой или недочитанный файл до замены шрифта. 16 МиБ — лимит примера, а не ограничение формата движка. Error.Ok означает принятие байтов: это не валидатор произвольных шрифтов. Проверьте формат, нужные символы и результат отображения; не используйте пример для непроверенных загрузок пользователей без отдельной проверки входных данных.

LoadDynamicFont — другой путь: он сам читает файл и сбрасывает настройки, но в 1.0.0 возвращает Error.Ok без проверки декодирования. Одного этого результата недостаточно. В примере чтение ограничено заранее; SetData нового ресурса не вызывает такой сброс.

Покрытие символов и shaping

Отсутствующий глиф требует подходящего fallback. Назначьте Font.Fallbacks в нужном порядке и проверяйте реальные строки языка, включая знаки, диакритику и эмодзи. HasChar полезен для одного символа, но не доказывает корректность всей письменности, лигатуры или последовательности emoji. Системный fallback зависит от устройства. Для icon font храните стабильное соответствие кодовой точки и значка, проверяйте версию файла.

Длина .NET string измеряется UTF-16 единицами; она не равна числу видимых графем. RTL, комбинируемые символы, лигатуры и IME требуют TextServer/shaping, а не ручной расстановки букв. Сначала разрешите перенос и выделите ширину, затем проверяйте выравнивание и TextDirection. Scale всего Control не заменяет размер шрифта.

Качество и специальные возможности шрифта

НастройкаКогда полезна / ограничение
AntialiasingВыбор сглаживания; для пиксельного шрифта проверьте режим без сглаживания и целые координаты
HintingПодгонка динамического шрифта к пиксельной сетке, особенно на малых размерах
SubpixelPositioningТочность положения; влияет на кеш и характер движения мелкого текста
MipmapsПомогают при уменьшении, требуют памяти; не лечат низкое исходное разрешение bitmap
MSDF, MsdfSize, MsdfPixelRangeМасштабирование и контуры на расстояниях, поддерживаемых выбранными параметрами; проверьте мелкие размеры и артефакты
Outline/shadow у ControlЦвет, размер контура и смещение тени задаются элементами темы; оставьте место до границ и clipping
Variable fontFontVariation.VariationOpentype задаёт поддержанные оси. Используйте числовой ключ TextServerManager.GetPrimaryInterface().NameToTag("wght"); диапазоны берите из GetSupportedVariationList. Строка "wght" в 1.0.0 может не изменить выбранный кэш
Faux bold/italicVariationEmbolden и VariationTransform синтезируют начертание; это не замена отдельного качественного bold/italic файла
Spacing / baselineFontVariation меняет интервалы и смещение; повторно проверьте строки и высоту элементов
OpenType featuresИспользуйте поддержанные файлом теги через OpentypeFeatures; лигатуры/цифры зависят от шрифта. Это отдельная настройка от осей FontVariation.VariationOpentype
Цветные emojiНужны покрытие и поддерживаемый цветной формат; проверьте текст на целевой платформе
PrerenderingНастройки импорта могут заранее создать нужные глифы/размеры; это обмен времени первого показа на размер и память

Форматы динамического импорта включают TTF/OTF/WOFF/WOFF2; свойства доступны в FontFile и расширенных параметрах импорта. Для bitmap качество ограничено исходными изображениями и выбранным масштабом. Не включайте все варианты размеров и осей заранее без оценки памяти.

У нового FontFile MsdfPixelRange = 16, MsdfSize = 48, SubpixelPositioning = Auto. После LoadDynamicFont значения сбрасываются на 14, 128 и Disabled соответственно. Параметры качества задавайте после загрузки. MSDF не поддерживает hinting; Oversampling обходится для MSDF и положительного FixedSize. Точные настройки FontFile.

Настройки проекта и диагностика

Общий ресурс задаёт gui/theme/custom_font; качество встроенного шрифта — gui/theme/default_font_*, масштаб темы — gui/theme/default_theme_scale. Учитывайте требования перезапуска и переимпорта. Проверенные ошибки чтения в примере сохраняют прежний шрифт; содержимое успешно прочитанного файла требует отдельной проверки.

Если видны квадраты — проверьте покрытие и fallback. Если текст обрезан — ширину, перенос, минимальные размеры, clipping и контур. Если после экспорта другой вид — наличие ресурсов и использование SystemFont. Если первый показ тормозит — набор кешируемых глифов/размеров и импорт, а не только FPS игры. Тест этой статьи использует приватный TTF Windows для проверки загрузчиков; файл шрифта не распространяется с примером.

Документация Reckfell EngineНаверх ↑
БЫСТРЫЙ ПЕРЕХОДНачало работыEntity и иерархияC# & .NET 10Сцены и префабы
Руководства и полный API Reckfell K
reckfellENGINE
RECKFELL ACCOUNT

Вход в аккаунт

Войдите в аккаунт Reckfell.

Один аккаунт для всей платформы Reckfell.