Такая ситуация. Имеется текстовый файл, где текст хранится в Unicode. Нужно прочитать этот файл и в окне нарисовать все символы с помощью функции TextOutW. Пусть в текстовом файле будут например 3 символа кириллицы, потом 3 китайских иероглифа, потом 3 символа из арабского алфавита. Так вот, чтобы с помощью TextOutW нарисовать символ, в контекст устройства нужно выбрать нужный шрифт - шрифт, который содержит нужные нам символы. Вот такие шрифты как Courier New, Arial, Times New Roman содержат символы кириллицы, иврита, арабского и т.д., но иероглифы китайского или японского содержатся в других шрифтах. Так вот перед рисованием нам нужно как-то перечислять шрифты в системе и обнаруживать, есть ли в них к примеру рисуемый в данный момент символ кириллицы или китайский иероглиф. И еще, как прочитав unicode код символа из файла, определить к каким символам он относится - к кириллице, арабского или китайскому и т.д. Мне все это нужно, чтобы рисовать текст в своем контроле, я не хочу использовать уже готовые, как edit. Я хочу узнать, как это делается по-человески. Пока свое решение такое: ----------------------- 1. Перечислять шрифты в системе с помощью функции EnumFontFamiliesEx. 2. С помощью таблицы "Unicode Subset Bitfields" определять к какому диапазону относится код символа. Небольшой кусок этой таблицы: 9, 0x0400, 0x04FF, "Cyrillic" 10, 0x0530, 0x058F, "Armenian" 11, 0x0590, 0x05FF, "Basic Hebrew" 12, 0x0, 0x0, "Reserved" 13, 0x0600, 0x06FF, "Basic Arabic" 3. Искать в каждом шрифте unicode код нужного символа с помощью функции GetTextCharsetInfo и индекса, соответствующего диапазону символов из той же таблицы "Unicode Subset Bitfields". Например, для кириллицы этот индекс 9, как видно в первом поле в таблице выше. 4. Если шрифт содержит нужный код символа, то рисовать символ функцией TextOutW с использованием найденного шрифта. 5. Выбирать следующий символ из файла и проверять если ли он в текущем шрифте, а если нет, то все начиная с пункта 1.
Мое решение, которые я предложил в предыдущем сообщении, на практике не совсем работает. Например, перебирая шрифты с помощью EnumFontFamiliesEx, и потом проверяя их с помощью GetTextCharsetInfo узнаем, что шрифт Gulimche.ttf поддерживает кучу диапазонов - там и кириллица, и хирагана, и катакана, и корейский, и китайский (поле fsUsb[4] структуры FONTSIGNATURE), а кодовая страница только 936 корейская (поле fsCsb[2] структуры FONTSIGNATURE). Поэтому если опираться только на fsUsb, получаются всякие косяки - для части китайских символов в Gulimche.ttf нет отображения, а символы кириллицы этим шрифтом выглядят как-то совсем эпически И таких ситуаций очень много, когда вроде диапазон unicode поддерживается, но на самом деле вместо символов рисуются квадратики. В общем, вот здесь привожу текстовый файл для примера, из которого в идеале нужно получить такую картинку (размер шрифтов для наглядности большой). Так получается, если в системе есть универсальный шрифт как arialuni.ttf (23 Мб). _1342854207__testunichar.zip
Интересно было бы посмотреть в связи с этим текст утилиты CHARMAP (Таблица символов) или оконную процедуру контрола EDIT. Может кто поделится, у кого есть исходники Windows 2000?
Есть функция GetFontUnicodeRanges, но она доступна только в Win 2000/XP. Поэтому имхо нужно использовать эту функцию, если она есть (проверить LoadLibrary и GetProcAddress). Если нет, выкручиваться тем способом, который ты предложил. Под Win 9x тот алгоритм, который ты описал - это практически единственный вариант. Microsoft в презентации по RichEdit'у упоминает, что наличие отдельных символов в шрифте можно проверить с помощью какой-то cmap (насколько я понял, это внутренняя структура в True Type-файле). Но никакой API-функции для работы с этой cmap я не нашел. То есть проверить под Win 9x, есть ли отдельный символ в шрифте, сложно или вообще невозможно; можно лишь выполнить GetTextCharsetInfo и узнать, что шрифт поддерживает определенную кодировку или диапазон Unicode. При этом, как ты говоришь, совсем не факт, что в диапазоне Unicode содержатся абсолютно все символы (этого вообще никто не может гарантировать, потому что в каждой новой версии стандарта Unicode в существующие диапазоны добавляются новые символы). А что ты пишешь, если не секрет? Я пару лет занимался созданием своего текстового редактора, может, сможем помочь друг другу? Внешне твое творение слегка смахивает на charmap.
наличие отдельных символов в шрифте можно проверить с помощью какой-то cmap (насколько я понял, это внутренняя структура в True Type-файле). Но никакой API-функции для работы с этой cmap я не нашел. Видел GetFontData для работы со всякими cmap и т.д. А вообще cmap и другие таблицы описаны в "True Type Font Specification" от Microsoft. Кстати, в CHARMAP тоже используется GetFontData и как раз читается таблица 'cmap', но в реверсинге я не силен. А что ты пишешь, если не секрет? Я пару лет занимался созданием своего текстового редактора, может, сможем помочь друг другу? Внешне твое творение слегка смахивает на charmap. Да ничего не пишу, а скорее учусь, пытаюсь что-то понять. Просто хочу чтобы были свои контролы под Win9x с поддержкой Unicode, но это только мечты пока. Посмотрел исходные тексты ReactOS, а именно контрол EDIT, но там все рисуется одним шрифтом, ничего не подбирается.
Почему мечта? Собственно ты уже знаешь все, что нужно для того, чтобы проверить, существует ли символ в шрифте. Осталось написать программу. Юзай GetFontData(cmap) и двоичный поиск нужного диапазона в Win 9x, а в Win 2000/XP - GetFontUnicodeRanges. Посмотри еще вот эту страницу: http://www.microsoft.com/globaldev/getwr/steps/wrg_font.mspx
Вообще-то есть ещё такая штука как FontLink. К примеру, "Microsoft Sans Serif" по умолчанию прилинкован к MS UI Gothic, Gulim, SimSun и PMingLiU. Т.е., хоть этот шрифт формально и не поддерживает восточноазиатские языки, при выводе они будут вполне нормально отображаться. Так же можно посмотреть в сторону IMLangFontLink.