Как предпочесть шрифт, загружаемый AddFontMemResourceEx, чем системный? - PullRequest
1 голос
/ 04 мая 2019

Я разрабатываю игровое приложение для Windows на C ++ со шрифтом, который включен в ресурс.

Я могу загрузить шрифт AddFontMemResourceEx и CreateFont.
И я могу сделатьтекст с загруженным шрифтом правильно в моей среде, который не устанавливает какой-либо специальный шрифт.

Но в мире существует несколько версий шрифта.
Если в системе уже установлена ​​другая версия, CreateFontнайдет шрифт по имени шрифта (pszFaceName) и предпочтет системный шрифт неудобно.
Есть ли какой-либо способ предпочесть частный шрифт, загружаемый AddFontMemResourceEx?

FYI, Возвращаемое значение AddFontMemResourceEx is HANDLE, но я не могу найти код, который использует его для CreateFont.
Возможно, редактирование семейства шрифтов для частного шрифта поможет избежать конфликта.Но я хочу решить путем программирования, если смогу.

HANDLE handle = AddFontMemResourceEx(data, readBytes, NULL, &fontNum);

hFont = CreateFont(24, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, SHIFTJIS_CHARSET, OUT_TT_ONLY_PRECIS,
                   CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"UmePlus CL Gothic");

1 Ответ

0 голосов
/ 10 мая 2019

Спасибо за комментарии!
Я заменил имя шрифта в памяти на основе комментария.

Но этот код немного усложняется из-за разницы в порядке байтов.

Внимание: newFontName должно быть меньше oldFontName.

#pragma pack(1)
typedef struct {
    short version;
    long numTables;
    short searchRange;
    short entrySelector;
    short rangeShift;
} TTF_HEADER;

typedef struct {
    char name[4];
    long checksum;
    long offset;
    long length;
} TTF_OFFSET_TABLE;

typedef struct {
    short format;
    short count;
    short stringOffset;
} TTF_NAME_TABLE_HEADER;

typedef struct {
    short platformId;
    short specificId;
    short languageId;
    short nameId;
    short length;
    short offset;
} TTF_NAME_TABLE_ENTRY;
#pragma pack()

void copySwappedWchar(const wchar_t* src, wchar_t* dest, int length) {
    for (int i = 0; i < length; i++) {
        dest[i] = _byteswap_ushort(src[i]);
    }
}

void renameLocalFont(unsigned char* data, const wchar_t* oldFontName, const wchar_t* newFontName) {
    TTF_HEADER* header = (TTF_HEADER*)data;
    unsigned char* offsetTableBase = data + sizeof(TTF_HEADER);
    for (int i = 0; i < _byteswap_ulong(header->numTables); i++) {
        TTF_OFFSET_TABLE* table = (TTF_OFFSET_TABLE*)(offsetTableBase + sizeof(TTF_OFFSET_TABLE) * i);
        if (memcmp(table->name, "name", 4) != 0) continue;

        TTF_NAME_TABLE_HEADER* nameTable = (TTF_NAME_TABLE_HEADER*)(data + _byteswap_ulong(table->offset));
        unsigned char* entryBase = data + _byteswap_ulong(table->offset) + sizeof(TTF_NAME_TABLE_HEADER);
        for (int j = 0; j < _byteswap_ushort(nameTable->count); j++) {
            TTF_NAME_TABLE_ENTRY* entry = (TTF_NAME_TABLE_ENTRY*)(entryBase + sizeof(TTF_NAME_TABLE_ENTRY) * j);
            wchar_t* dest = new wchar_t[_byteswap_ushort(entry->length) + 1];
            wchar_t* src = (wchar_t*)(data + _byteswap_ulong(table->offset) + _byteswap_ushort(nameTable->stringOffset) + _byteswap_ushort(entry->offset));
            copySwappedWchar((const wchar_t*)src, dest, _byteswap_ushort(entry->length) + 1);
            if (wcscmp(dest, oldFontName) == 0) {
                copySwappedWchar(newFontName, src, wcslen(newFontName) + 1);
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...