Новости В Of Ash and Steel начался закрытый плейтест
  • 885
  • 1
Разработчики "Русской Готики" объявили о старте закрытого плейтеста. Если вы оставляли заявку на участие, не забудьте проверить электронную почту или посмотреть свою библиотеку - возможно игра уже...
С Днём России!
  • 3.196
  • 6
Дорогие друзья! Поздравляю вас с Днём России! Этот праздник напоминает нам о богатой истории и культуре нашей страны, о её величии и непоколебимом духе народа! Желаю вам крепкого здоровья...
Новости Анонсирован Atomic Heart II
Новости Анонсирован ремастер Final Fantasy Tactics
  • 1.392
  • 1
Культовая пошаговая тактическая RPG от Square Enix получит второе дыхание. На проходящей выставке State of Play, где анонсируются игры для Play Station, состоялся анонс ремастера Final Fantasy...
Поддержка TTF и OTF шрифтов.

Поддержка TTF и OTF шрифтов. 1.1

Нет прав доступа на загрузку
Этот патч добавляет совместимость Нового Баланса с отличным модом что позволяет использовать любые в

ToXaL1

Рыцарь
Участник форума
Регистрация
8 Окт 2017
Сообщения
2.714
Реакции
593
Баллы
230
Лучшие ответы
38
#41
@Blackmail01, хммм выходит otf то лучше и хорошо что есть поддержка))
 

Хедин

Живая легенда
Пользователь VIP
Модостроитель
Почётный пользователь
Участник форума
Регистрация
10 Июл 2013
Сообщения
6.559
Реакции
8.854
Баллы
816
Лучшие ответы
130
#42
@ToXaL1, Отличия в основном в технической части. Просто некоторые шрифты представлены только в формате otf, и их, как оказалось тоже можно использовать запросто. Также прописываешь в ini
Посмотреть вложение 155059
Шрифты TTF (TrueType Font) и OTF (OpenType Font) — это два популярных формата цифровых шрифтов, и их различия касаются технических возможностей, поддержки функций и истории создания. Вот ключевые отличия:

1. Технология и структура
  • TTF:
    Использует квадратичные кривые Безье для описания контуров символов.
    Содержит данные только для одного набора символов (обычно базовой латиницы).
    Хинтинг (инструкции для улучшения читаемости на экране) реализован проще.
  • OTF:
    Поддерживает кривые PostScript (кубические Безье), что позволяет создавать более сложные и плавные формы.
    Может включать дополнительные данные (множество языков, альтернативные глифы, лигатуры и т.д.) в одном файле.
    Хинтинг более продвинутый (например, через технологию CFF — Compact Font Format).
2. Функциональные возможности
  • TTF:
    Ограничен базовыми возможностями: стандартные символы, простые кернинг (расстояние между буквами) и лигатуры.
    Подходит для простых задач (офисные документы, веб на среднем уровне).
  • OTF:
    Поддерживает расширенные типографские функции:
    • Альтернативные стили букв (swash, стилистические наборы).
    • Автоматические лигатуры (например, для соединения "f" и "i").
    • Контекстные замены (буква меняет форму в зависимости от соседних символов).
    • Поддержка тысяч глифов (включая иероглифы, редкие символы).
    • Улучшенный кернинг и вертикальное выравнивание.
      Идеален для профессионального дизайна, полиграфии, мультиязычных проектов.
3. Совместимость
  • TTF:
    Работает на всех ОС (Windows, macOS, Linux) и в большинстве программ, но может иметь проблемы с отображением сложной типографики.
  • OTF:
    Также кроссплатформенный, но для использования всех функций нужна поддержка со стороны ПО (например, InDesign, Illustrator, современные браузеры).
    Старые программы (например, Office 2007) могут открывать OTF, но игнорируют расширенные возможности.
4. Сжатие и размер файла
  • TTF:
    Обычно имеет меньший размер для простых шрифтов.
  • OTF:
    Может быть компактнее при использовании CFF-сжатия для PostScript-контуров (особенно для шрифтов с множеством символов).
5. История
  • TTF:
    Создан Apple и Microsoft в 1980-х как альтернатива PostScript-шрифтам Adobe.
  • OTF:
    Разработан Adobe и Microsoft в конце 1990-х, объединив лучшие черты TTF и PostScript.
Не обязятаельно прописывать новый шрифт в TTF.ini, я тестовый шрифты просто копирую в папку fonts

1749079593226.png
и потом переименовываю нужный шрифт в G2_GothicFont.ttf

1749079639679.png
 

ToXaL1

Рыцарь
Участник форума
Регистрация
8 Окт 2017
Сообщения
2.714
Реакции
593
Баллы
230
Лучшие ответы
38
#43
@Хедин, ну вы шарите в этом я так только начинаю))) с++ еще учу да и все остальное пока не лезу в то что не знаю!
 
Автор
Автор
Blackmail01

Blackmail01

Гвардеец
Команда форума
Редактор раздела
Участник форума
Регистрация
27 Дек 2019
Сообщения
1.124
Реакции
1.163
Баллы
251
Лучшие ответы
68
#44
@Хедин, Тоже себе вариант. Я уж привык. Частенько меняю шрифты, смотрю. Да и в notepad++ это дело быстрое.
TTF.dll пересобрал разве что. Добавил параметр FONTSIZE_MULTIPLIER. Меняет множитель размера шрифта. Скейлинг через systempack.ini не нравится, а считать и менять под каждый шрифт size отдельно не удобно было.

float g_fontSizeMultiplier = 1.0f;
Код:
static void ReadConfigurationFile()
{
    char cfgPath[MAX_PATH];
    GetModuleFileNameA(GetModuleHandleA(nullptr), cfgPath, sizeof(cfgPath));
    PathRemoveFileSpecA(cfgPath);
    strcat_s(cfgPath, "\\TTF.ini");

    // Установка значений по умолчанию
    g_fontSizeMultiplier = 1.0f; // Множитель размера шрифта по умолчанию
    g_useScaling = true;         // Масштабирование включено по умолчанию
    g_useEncoding = 0;           // Кодировка по умолчанию (UTF-8)

    FILE* f;
    errno_t err = fopen_s(&f, cfgPath, "r");
    if(err == 0)
    {
        std::string currentSector = "none";

        char readedLine[1024];
        while(fgets(readedLine, sizeof(readedLine), f) != nullptr)
        {
            size_t len = strlen(readedLine);
            if(len > 0)
            {
                if(readedLine[len - 1] == '\n' || readedLine[len - 1] == '\r')
                    len -= 1;
                if(len > 0)
                {
                    if(readedLine[len - 1] == '\n' || readedLine[len - 1] == '\r')
                        len -= 1;
                }
            }
            if(len == 0)
                continue;

            if(readedLine[0] == '[' && readedLine[len - 1] == ']')
            {
                currentSector = std::string(readedLine + 1, len - 2);
                std::transform(currentSector.begin(), currentSector.end(), currentSector.begin(), toupper);
            }
            else if(readedLine[0] != ';' && readedLine[0] != '/')
            {
                std::size_t eqpos;
                std::string rLine = std::string(readedLine, len);
                std::transform(rLine.begin(), rLine.end(), rLine.begin(), toupper);
                if((eqpos = rLine.find("=")) != std::string::npos)
                {
                    std::string lhLine = rLine.substr(0, eqpos);
                    std::string rhLine = rLine.substr(eqpos + 1);
                    lhLine.erase(lhLine.find_last_not_of(' ') + 1);
                    lhLine.erase(0, lhLine.find_first_not_of(' '));
                    rhLine.erase(rhLine.find_last_not_of(' ') + 1);
                    rhLine.erase(0, rhLine.find_first_not_of(' '));
                    if(currentSector == "CONFIGURATION")
                    {
                        if(lhLine == "SCALEFONTS")
                        {
                            g_useScaling = (rhLine == "TRUE" || rhLine == "1");
                        }
                        else if(lhLine == "CODEPAGE")
                        {
                            if(rhLine == "WINDOWS-1250" || rhLine == "WINDOWS1250" || rhLine == "WINDOWS 1250" || rhLine == "1250")
                                g_useEncoding = 1250;
                            else if(rhLine == "WINDOWS-1251" || rhLine == "WINDOWS1251" || rhLine == "WINDOWS 1251" || rhLine == "1251")
                                g_useEncoding = 1251;
                            else if(rhLine == "WINDOWS-1252" || rhLine == "WINDOWS1252" || rhLine == "WINDOWS 1252" || rhLine == "1252")
                                g_useEncoding = 1252;
                            else if(rhLine == "WINDOWS-1253" || rhLine == "WINDOWS1253" || rhLine == "WINDOWS 1253" || rhLine == "1253")
                                g_useEncoding = 1253;
                            else if(rhLine == "WINDOWS-1254" || rhLine == "WINDOWS1254" || rhLine == "WINDOWS 1254" || rhLine == "1254")
                                g_useEncoding = 1254;
                            else if(rhLine == "WINDOWS-1255" || rhLine == "WINDOWS1255" || rhLine == "WINDOWS 1255" || rhLine == "1255")
                                g_useEncoding = 1255;
                            else if(rhLine == "WINDOWS-1256" || rhLine == "WINDOWS1256" || rhLine == "WINDOWS 1256" || rhLine == "1256")
                                g_useEncoding = 1256;
                            else if(rhLine == "WINDOWS-1257" || rhLine == "WINDOWS1257" || rhLine == "WINDOWS 1257" || rhLine == "1257")
                                g_useEncoding = 1257;
                            else if(rhLine == "WINDOWS-1258" || rhLine == "WINDOWS1258" || rhLine == "WINDOWS 1258" || rhLine == "1258")
                                g_useEncoding = 1258;
                            else
                                g_useEncoding = 0;
                        }
                        // Обработка нового параметра - множителя размера шрифта
                        else if(lhLine == "FONTSIZE_MULTIPLIER")
                        {
                            try {
                                g_fontSizeMultiplier = std::stof(rhLine);
                                // Защита от некорректных значений
                                if(g_fontSizeMultiplier < 0.1f)
                                    g_fontSizeMultiplier = 0.1f;
                                else if(g_fontSizeMultiplier > 10.0f)
                                    g_fontSizeMultiplier = 10.0f;
                            }
                            catch(const std::exception&) {
                                g_fontSizeMultiplier = 1.0f;
                            }
                        }
                    }
                    else if(currentSector == "FONTS")
                    {
                        g_fontsWrapper.emplace(lhLine, rhLine);
                    }
                }
            }
        }
        fclose(f);
    }
}
Код:
int __fastcall G1_zCFont_LoadFontTexture(DWORD zCFont, DWORD _EDX, zSTRING_G2& fName)
{
    int size = 20, r = 0xFF, g = 0xFF, b = 0xFF, a = 0xFF;
    std::string fontName(fName.ToChar(), fName.Length());
    std::transform(fontName.begin(), fontName.end(), fontName.begin(), toupper);
    if(fontName.find(':') == std::string::npos)
    {
        auto it = g_fontsWrapper.find(fontName);
        if(it == g_fontsWrapper.end())
        {
            it = g_fontsWrapper.find("DEFAULT");
            if(it == g_fontsWrapper.end())
                return 0;
        }
        fontName.assign(it->second);
    }

    std::string fntName;
    ReadFontDetails(fontName, fntName, size, r, g, b, a);
    if(g_useBGRA) std::swap(r, b);

    // Применение множителя размера шрифта
    if(g_useScaling && *reinterpret_cast<BYTE*>(0x6E0238) == 0xE9)
    {
        float UIscale = *reinterpret_cast<float*>(*reinterpret_cast<DWORD*>(0x5A88E1));
        size = static_cast<int>(size * UIscale * g_fontSizeMultiplier);
    }
    else
    {
        // Применяем множитель даже если масштабирование интерфейса отключено
        size = static_cast<int>(size * g_fontSizeMultiplier);
    }
    *reinterpret_cast<int*>(zCFont + 0x14) = size;

    zSTRING_G2& path = reinterpret_cast<zSTRING_G2&(__thiscall*)(DWORD, int)>(0x45FC00)(*reinterpret_cast<DWORD*>(0x869694), 23);
    fntName.insert(0, "\\_WORK\\FONTS\\G1_");
    fntName.insert(0, path.ToChar(), path.Length());

    TTFont* ttFont = new TTFont;
    ttFont->r = r; ttFont->g = g; ttFont->b = b; ttFont->a = a;
    *reinterpret_cast<TTFont**>(zCFont + 0x20) = ttFont;
    if(FT_New_Face(g_ft, fntName.c_str(), 0, &ttFont->fontFace))
    {
        MessageBoxW(nullptr, L"Failed to load font", L"Gothic TTF", MB_ICONHAND);
        exit(-1);
    }
    for(int i = 0; i < ttFont->fontFace->num_charmaps; ++i)
    {
        FT_CharMap charmap = ttFont->fontFace->charmaps[i];
        if((charmap->platform_id == 3 && charmap->encoding_id == 1) /* Windows Unicode */
            || (charmap->platform_id == 3 && charmap->encoding_id == 0) /* Windows Symbol */
            || (charmap->platform_id == 2 && charmap->encoding_id == 1) /* ISO Unicode */
            || (charmap->platform_id == 0)) /* Apple Unicode */
        {
            FT_Set_Charmap(ttFont->fontFace, charmap);
            break;
        }
    }

    FT_Set_Pixel_Sizes(ttFont->fontFace, 0, size);
    if(FT_IS_SCALABLE(ttFont->fontFace))
    {
        FT_Fixed scale = ttFont->fontFace->size->metrics.y_scale;
        int height = FT_MulFix(ttFont->fontFace->height, scale);
        int ascent = FT_MulFix(ttFont->fontFace->ascender, scale);
        int descent = FT_MulFix(ttFont->fontFace->descender, scale);
        *reinterpret_cast<int*>(zCFont + 0x24) = static_cast<int>(((height + 63) & -64) / 64);
        *reinterpret_cast<int*>(zCFont + 0x28) = static_cast<int>(((ascent + 63) & -64) / 64);
        *reinterpret_cast<int*>(zCFont + 0x2C) = static_cast<int>(((descent + 63) & -64) / 64);
    }
    else
    {
        *reinterpret_cast<int*>(zCFont + 0x24) = static_cast<int>(((ttFont->fontFace->size->metrics.height + 63) & -64) / 64);
        *reinterpret_cast<int*>(zCFont + 0x28) = static_cast<int>(((ttFont->fontFace->size->metrics.ascender + 63) & -64) / 64);
        *reinterpret_cast<int*>(zCFont + 0x2C) = static_cast<int>(((ttFont->fontFace->size->metrics.descender + 63) & -64) / 64);
    }

    g_fonts.emplace(ttFont);
    return 1;
}
Код:
int __fastcall G2_zCFont_LoadFontTexture(DWORD zCFont, DWORD _EDX, zSTRING_G2& fName)
{
    int size = 20, r = 0xFF, g = 0xFF, b = 0xFF, a = 0xFF;
    std::string fontName(fName.ToChar(), fName.Length());
    std::transform(fontName.begin(), fontName.end(), fontName.begin(), toupper);
    if(fontName.find(':') == std::string::npos)
    {
        auto it = g_fontsWrapper.find(fontName);
        if(it == g_fontsWrapper.end())
        {
            it = g_fontsWrapper.find("DEFAULT");
            if(it == g_fontsWrapper.end())
                return 0;
        }
        fontName.assign(it->second);
    }

    std::string fntName;
    ReadFontDetails(fontName, fntName, size, r, g, b, a);
    if(g_useBGRA) std::swap(r, b);

    // Применение множителя размера шрифта
    if(g_useScaling && *reinterpret_cast<BYTE*>(0x789518) == 0xE9)
    {
        float UIscale = *reinterpret_cast<float*>(*reinterpret_cast<DWORD*>(0x66714F));
        size = static_cast<int>(size * UIscale * g_fontSizeMultiplier);
    }
    else
    {
        // Применяем множитель даже если масштабирование интерфейса отключено
        size = static_cast<int>(size * g_fontSizeMultiplier);
    }
    *reinterpret_cast<int*>(zCFont + 0x14) = size;

    zSTRING_G2& path = reinterpret_cast<zSTRING_G2&(__thiscall*)(DWORD, int)>(0x465260)(*reinterpret_cast<DWORD*>(0x8CD988), 24);
    fntName.insert(0, "\\_WORK\\FONTS\\G2_");
    fntName.insert(0, path.ToChar(), path.Length());

    TTFont* ttFont = new TTFont;
    ttFont->r = r; ttFont->g = g; ttFont->b = b; ttFont->a = a;
    *reinterpret_cast<TTFont**>(zCFont + 0x20) = ttFont;
    if(FT_New_Face(g_ft, fntName.c_str(), 0, &ttFont->fontFace))
    {
        MessageBoxW(nullptr, L"Failed to load font", L"Gothic TTF", MB_ICONHAND);
        exit(-1);
    }
    for(int i = 0; i < ttFont->fontFace->num_charmaps; ++i)
    {
        FT_CharMap charmap = ttFont->fontFace->charmaps[i];
        if((charmap->platform_id == 3 && charmap->encoding_id == 1) /* Windows Unicode */
            || (charmap->platform_id == 3 && charmap->encoding_id == 0) /* Windows Symbol */
            || (charmap->platform_id == 2 && charmap->encoding_id == 1) /* ISO Unicode */
            || (charmap->platform_id == 0)) /* Apple Unicode */
        {
            FT_Set_Charmap(ttFont->fontFace, charmap);
            break;
        }
    }

    FT_Set_Pixel_Sizes(ttFont->fontFace, 0, size);
    if(FT_IS_SCALABLE(ttFont->fontFace))
    {
        FT_Fixed scale = ttFont->fontFace->size->metrics.y_scale;
        int height = FT_MulFix(ttFont->fontFace->height, scale);
        int ascent = FT_MulFix(ttFont->fontFace->ascender, scale);
        int descent = FT_MulFix(ttFont->fontFace->descender, scale);
        *reinterpret_cast<int*>(zCFont + 0x24) = static_cast<int>(((height + 63) & -64) / 64);
        *reinterpret_cast<int*>(zCFont + 0x28) = static_cast<int>(((ascent + 63) & -64) / 64);
        *reinterpret_cast<int*>(zCFont + 0x2C) = static_cast<int>(((descent + 63) & -64) / 64);
    }
    else
    {
        *reinterpret_cast<int*>(zCFont + 0x24) = static_cast<int>(((ttFont->fontFace->size->metrics.height + 63) & -64) / 64);
        *reinterpret_cast<int*>(zCFont + 0x28) = static_cast<int>(((ttFont->fontFace->size->metrics.ascender + 63) & -64) / 64);
        *reinterpret_cast<int*>(zCFont + 0x2C) = static_cast<int>(((ttFont->fontFace->size->metrics.descender + 63) & -64) / 64);
    }

    g_fonts.emplace(ttFont);
    return 1;
}
 

Хедин

Живая легенда
Пользователь VIP
Модостроитель
Почётный пользователь
Участник форума
Регистрация
10 Июл 2013
Сообщения
6.559
Реакции
8.854
Баллы
816
Лучшие ответы
130
#45
@Blackmail01, если надо, то могу добавить твой множитель в свою версию. Но вроде с моей версией итак нормально показывается. Я сильно размер и не трогаю в TTF.ini, выставил 20 и все. Мне главное что бы нормально менялся размер шрифта внутри баров (особенно в фокусном баре) инвентаре

16.jpg 17.jpg 18.jpg

Я кстати ScaleFonts = False выставил себе.
 
Автор
Автор
Blackmail01

Blackmail01

Гвардеец
Команда форума
Редактор раздела
Участник форума
Регистрация
27 Дек 2019
Сообщения
1.124
Реакции
1.163
Баллы
251
Лучшие ответы
68
#46
@Blackmail01, если надо, то могу добавить твой множитель в свою версию. Но вроде с моей версией итак нормально показывается. Я сильно размер и не трогаю в TTF.ini, выставил 20 и все. Мне главное что бы нормально менялся размер шрифта внутри баров (особенно в фокусном баре) инвентаре

Посмотреть вложение 155070 Посмотреть вложение 155071 Посмотреть вложение 155072

Я кстати ScaleFonts = False выставил себе.
Я тоже ScaleFonts = False выставил себе.
Было бы здорово если добавишь. Со шрифтами такое дело что они сами по себе бывают разного размера. Некоторые с множителем 1.4 хорошо смотрятся, другие с 1 прекрасно.
 

Хедин

Живая легенда
Пользователь VIP
Модостроитель
Почётный пользователь
Участник форума
Регистрация
10 Июл 2013
Сообщения
6.559
Реакции
8.854
Баллы
816
Лучшие ответы
130
#47
@Blackmail01, обновил на яндекс диске
 

ToXaL1

Рыцарь
Участник форума
Регистрация
8 Окт 2017
Сообщения
2.714
Реакции
593
Баллы
230
Лучшие ответы
38
#48
@Хедин, а ссылку можно? хочу глянуть!
 
Автор
Автор
Blackmail01

Blackmail01

Гвардеец
Команда форума
Редактор раздела
Участник форума
Регистрация
27 Дек 2019
Сообщения
1.124
Реакции
1.163
Баллы
251
Лучшие ответы
68
#49

Санчес

Гвардеец
Участник форума
Регистрация
9 Май 2021
Сообщения
1.208
Реакции
376
Баллы
162
Лучшие ответы
23
#50
Сверху Снизу