Windows: получение контуров глифов для символов замены из других шрифтов

Мне нужно визуализировать шрифты в трехмерном игровом мире, поэтому я использую функцию контура GetGlyphOutline, чтобы получить формы глифов для визуализации в текстуру. Тем не менее, я хочу иметь возможность обрабатывать случай, когда символы отсутствуют в данном шрифте (как это часто бывает с другим другим международным текстом в Азии). Рендеринг текста Windows автоматически заменит шрифты с необходимыми символами. Но GetGlyphOutline не будет. Как я могу определить этот случай и получить очертания замененных глифов? В Mac OS X Core Text есть функция для получения подходящего заменяющего шрифта для заданного шрифта и строки - есть ли что-нибудь подобное в Windows?


person jonas echterhoff    schedule 01.12.2009    source источник


Ответы (2)


Я узнал то, что мне нужно было знать самому: интерфейс IMLangFontLink, особенно метод MapFont, содержат необходимую функциональность, чтобы узнать, какие заменяющие шрифты следует использовать в Windows.

person jonas echterhoff    schedule 01.12.2009
comment
Всегда ли в Windows установлена ​​интерфейсная библиотека IMLangFontLink? - person epotter; 02.12.2009
comment
Насколько я могу судить, его устанавливает Internet Explorer 4.0 или выше. Я не знаю, безопасно ли предполагать, что он есть в любой системе Windows, даже если IE был удален или нет. - person jonas echterhoff; 02.12.2009

Я тоже озадачил GetGlyphOutline. Я не уверен, что вы смогли сделать то же самое, но мне удалось получить текстовые контуры со смешанным шрифтом, используя TextOut() в сочетании с BeginPath(), EndPath() и GetPath().

Например, даже с использованием шрифта Arial я могу получить путь к японскому тексту 「テ ス ト」 (с использованием C ++, но это легко можно сделать и на C):

SelectObject(hdc, hArialFont);
BeginPath(hdc);
TextOut(hdc, 100, 100, L"\u30c6\u30b9\u30c8"); // auto font subbing
EndPath(hdc);

// get number of points in path
int pc = GetPath(hdc, NULL, NULL, 0);

if (pc > 0)
{
    std::vector<POINT> points(pc);
    std::vector<BYTE> types(pc); // PT_MOVETO, PT_LINETO, PT_BEZIERTO

    GetPath(hdc, &points[0], &types[0], pc);

    // it seems the first four points are the bounding rect
    // subsequent points match up to their types

    for (int i = 4; i < pc; i++)
    {
        if (types[i] == PT_LINETO)
            LineTo(hdc, points[i].x, points[i].y); // etc
    }
}
person dreamlax    schedule 06.01.2011
comment
Хотя это может сработать, разве использование LineTo для рендеринга шрифтов не дает вам только контур шрифта? Также вы не получите сглаживание, и будет ли он правильно обрабатывать кривые Безье в шрифтах TTF? - person jonas echterhoff; 20.01.2011
comment
@jonas: Все зависит от контекста устройства, на котором вы работаете (и от того, как он настроен). Также, если вы используете LineTo в BeginPath и EndPath, тогда ничего не будет нарисовано, пока вы не используете StrokePath или EndPath. Также это просто демонстрация того, что вы можете получить путь, когда у вас есть путь, вы можете выдавить его в 3D-объект или нарисовать его на экране. - person dreamlax; 20.01.2011