Ловушки японских шрифтов и символов — как обращаться с JIS2004, IVS и гайдзи в бизнес-приложениях
· Го Комура · Японские шрифты, JIS2004, Вариантные символы, Гайдзи, Кодировка символов, Unicode, Бизнес-приложения, Отчёты, Windows
«Символ 葛 в списке клиентов выглядит по-разному на экране и на печатной форме. Клиент пожаловался, что данные наверняка испорчены.» — В сопровождении бизнес-систем такие консультации не редкость. Другая частая: «символ в имени человека не отображается на документе, который мы подаём в учреждение. На старом ПК отображался; после замены стал □.»
Обе на местах склонны называть «искажением кодировки» (mojibake), но это другая проблема, чем искажение от несовпадения кодировки. В первой не изменился ни один бит данных и сменился только внешний вид; во второй потерян «гайдзи», который существовал только на том ПК.
flowchart TB
accTitle: Чем на деле являются две частые консультации
accDescr: Консультация, что 葛 выглядит по-разному на экране и на форме, — случай, когда сменился только внешний вид, а данные остались теми же; консультация, что символ стал □ после замены ПК, — случай, когда потерян гайдзи, существовавший только на том ПК; обе — другая проблема, чем искажение от несовпадения кодировки
c1["Консультация 1: форма различается на экране и на форме"] --> r1["Данные не изменились; сменился только вид"]
c2["Консультация 2: стал □ после замены"] --> r2["Гайдзи, существовавший только на том ПК, потерян"]
r1 --> diff["Другая проблема, чем искажение кодировки"]
r2 --> diff
Рис. 1: Две консультации, которые склонны называть «искажением кодировки», обе — другая проблема, чем несовпадение кодировки.
Обещание этой статьи простое. Если разделить слой кода символа (данные) и слой шрифта (внешний вид), большинство проблем японских символов становится разрешимым. От смены глифа JIS2004, идеографических селекторов вариации (IVS) и гайдзи (EUDC) через государственную платформу символов до выбора и встраивания шрифтов — собрано в форме, которой разработчики бизнес-систем и ИТ-сотрудники могут пользоваться для решений.
Само «искажение кодировки», которое случается при преобразовании Shift_JIS ↔ UTF-8, разобрано в существующих статьях, поэтому эта статья сосредоточена на проблеме «коды делают круговой проход правильно, но внешний вид или отображаемость сбиты».
1. Сначала вывод
- «Искажение кодировки» и «глиф другой» — разные проблемы. Искажение кодировки — авария на слое данных неверной интерпретации последовательности байтов; разница глифа — авария на слое внешнего вида разницы глифов, которые держит шрифт; средства совершенно разные.
- Даже при одной кодовой точке Unicode отображаемый глиф зависит от шрифта. JIS X 0213:2004 пересмотрел образцовые глифы 168 символов вроде 葛, 辻 и 飴 к печатным стандартным формам, и Windows тоже сделал глифы JIS2004 умолчанием в MS Gothic / MS Mincho начиная с Vista.12
- Стандартное средство зафиксировать глиф как данные — идеографический селектор вариации (IVS). Глиф указывают последовательностью базового символа плюс селектор начиная с U+E0100; коллекции вроде Adobe-Japan1, Hanyo-Denshi и Moji_Joho (Платформа символьной информации) зарегистрированы в IVD Unicode.34
- В неподдерживающей среде заданное поведение IVS — селектор игнорируется и отображается глиф по умолчанию базового символа. Один символ с IVS, однако, может занимать до четырёх кодовых единиц в UTF-16, поэтому реализации подсчёта и нарезки символов требуют осторожности.5
- У гайдзи (EUDC) судьба «может отображаться только на том ПК». У кодовой точки области частного использования нет согласованного смысла, и глиф, зарегистрированный в eudc.tte, не едет на другой ПК, в почту или в PDF.67
- Система, которая обрабатывает личные имена, должна решить принимаемый набор символов и заявить его. На государственной стороне, опираясь на унифицированные символы косэки и Платформу символьной информации, системы, соответствующие стандарту, движутся к использованию «стандартных символов для административных дел».8910
- Для форм и PDF база — «выровнять шрифт с экраном и встроить». Разрешено ли встраивание, определяет лицензия шрифта (fsType), а PDF/A для долгосрочного хранения требует встраивания шрифта.1112
- Не применяйте нормализацию (NFKC) к данным личных имён спустя рукава. Унификация полной и половинной ширины и замена символов совместимости теряют различия, которые следует сохранять.13
Одним предложением: «какую последовательность байтов вы храните» — задача проектирования данных; «как это выглядит» — задача проектирования шрифта. Если обсуждать их смешанно, даже проблемы, которые можно было починить, становятся непочинимыми.
2. Думать о данных и внешнем виде раздельно — кодовые точки и глифы
В Unicode символ представлен числом, называемым кодовой точкой. 葛 — U+845B, и это число одно и то же на каждом ПК. Как это число рисуется на экране или на бумаге, напротив, решает глиф, который держит шрифт. Нормальное поведение — что один и тот же U+845B различается в деталях формы между шрифтом A и шрифтом B.
С этими двумя слоями как предпосылкой полевые симптомы можно разделить так.
| Слой | Происходящая авария | Типичные симптомы | Главное средство |
|---|---|---|---|
| Слой данных (кодировка символов) | Неверная интерпретация кодировки, потеря при преобразовании | Искажение вроде 縺ッ, подстановка ? или 〓, U+FFFD (�) |
Найти и починить путь преобразования |
| Слой внешнего вида (шрифты) | Разница глифов по шрифту, отсутствующие глифы | Те же данные, но другая форма; становится □ (тофу) | Унифицировать или сменить шрифт; встроить |
Как подсказку для разделения полезно помнить разницу между «�» и «□». «�» U+FFFD (REPLACEMENT CHARACTER) — след сбоя преобразования на слое данных, и исходный символ уже потерян. «□», напротив, во многих случаях лишь то, что данные ещё есть, но у шрифта нет глифа, и смена шрифта может сделать его отображаемым.
flowchart TB
accTitle: Разделение симптома по � против □
accDescr: Когда символ отображается неправильно, � — след сбоя преобразования на слое данных, в котором исходный символ потерян; □ — лишь то, что данные ещё есть, но у шрифта нет глифа, и смена шрифта может сделать его отображаемым
symptom["Символ отображается неправильно"] --> which{"Что вы видите?"}
which -->|Видите �| datalayer["Авария на слое данных"]
datalayer -.-> lost["След сбоя преобразования (исходный символ потерян)"]
which -->|Видите □| viewlayer["Авария на слое внешнего вида"]
viewlayer -.-> noglyph["Лишь то, что у шрифта нет глифа"]
noglyph --> fixable["Смена шрифта может сделать отображаемым"]
Рис. 2: � — знак аварии на слое данных, □ — на слое внешнего вида, и точка входа расследования меняется.
Сами основы кодировок (CP932 и UTF-8, BOM, коды перевода строки) разобраны в «Введение в кодировки текста в Windows — искажение кодировки (mojibake), возникающее при интеграции с Linux» и «Кодировки текста и символы перевода строки в Windows — основы искажения кодировки и CRLF/LF». Дальше — слой внешнего вида и проблемы, которые возникают на его границе.
3. От JIS90 к JIS2004 — глиф сменился, а код остался тем же
Суть открывающего «葛 выглядит по-разному на экране и на форме» во многих случаях здесь.
Следуя докладу 2000 года Национального совета по языку «Hyogai Kanji Jitaihyo» (таблица форм символов для кандзи вне списка дзёё), пересмотр 2004 года JIS X 0213:2004 (обычно JIS2004) пересмотрел образцовые глифы 168 кандзи к печатным стандартным формам, близким к так называемым формам словаря Канси. 葛, 辻, 飴, 芦, 溢, 餅 и подобные — типичные примеры.1
Windows выровнялся и сделал глифы JIS2004 умолчанием в MS Gothic / MS Mincho (и вновь введённом Meiryo) начиная с Windows Vista. И нынешний MS Gothic тоже имеет глиф по умолчанию на базе JIS2004, со структурой, что глифы эпохи JIS90 доступны через возможность OpenType jp90.21
flowchart TB
accTitle: Структура глифов нынешнего MS Gothic
accDescr: Начиная с Vista у MS Gothic глифы JIS2004 по умолчанию, а доступ к глифам эпохи JIS90 через возможность OpenType jp90 — структура
msg["MS Gothic (с Vista)"] --> def["Глиф по умолчанию: на базе JIS2004"]
msg --> feat["Через возможность jp90"]
feat --> old["Глифы эпохи JIS90"]
Рис. 3: Нынешний MS Gothic имеет глифы JIS2004 по умолчанию и может переключаться на глифы JIS90 возможностью jp90.
Здесь важно то, что сменился только шрифт; данные не изменились вовсе.
- Кодовая точка 葛 — U+845B и на XP, и на Windows 11
- На XP (глифы JIS90) отображается в форме, которая упрощает внутренность охватывающего радикала до ヒ; начиная с Vista (глифы JIS2004) отображается в форме, которая пишет внутри также 人
- Поэтому отсканированный образ формы, напечатанной на старой системе, и экранное отображение на новом ПК расходятся в форме символа. Сравнение данных совпадает полностью
Один это или две точки у радикала синнё у 辻, форма радикала «есть» у 飴 и подобное — то же самое. Если не знать эту историю, расследование склонно идти в неверном направлении «данные испортились при миграции». Когда говорят, что внешний вид символа различается до и после миграции, сначала сравните кодовые точки, и если они совпадают, подозревайте разницу глифа шрифта — вот правильный порядок.
flowchart TB
accTitle: Одна кодовая точка, разный глиф в зависимости от шрифта
accDescr: Кодовая точка U+845B символа 葛 остаётся той же и на XP, и на Windows 11; меняется только отображаемая форма между шрифтом глифов JIS90 и шрифтом глифов JIS2004, и сравнение данных совпадает полностью
cp["Кодовая точка U+845B (葛)"] --> f90["Шрифт глифов JIS90 (XP)"]
cp --> f04["Шрифт глифов JIS2004 (с Vista)"]
f90 --> g90["Форма, упрощающая внутренность до ヒ"]
f04 --> g04["Печатная стандартная форма, пишущая внутри 人"]
g90 -.-> same["Сравнение данных совпадает полностью"]
g04 -.-> same
Рис. 4: Сменился только шрифт; кодовая точка U+845B остаётся той же в каждой среде.
Заметьте: поскольку сам символ не изменился, оба глифа — «один и тот же символ». В личных именах, однако, человек или учреждение иногда настаивают на конкретной форме, и ответить на требование различать это «как данные» — следующая тема, IVS.
4. Идеографические селекторы вариации (IVS) — указание глифа как данных
IVS (Ideographic Variation Sequence) — механизм, который ставит невидимую кодовую точку, называемую «идеографическим селектором вариации», сразу после кандзи, чтобы указать вариант глифа как данные. Используемые селекторы — U+E0100–U+E01EF (VS17–VS256).3
Какая последовательность «базовый символ + селектор» относится к какому глифу, решает реестр под названием IVD (Ideographic Variation Database), которым управляет Консорциум Unicode. Основные коллекции такие.4
| Коллекция | Зарегистрирована | Происхождение и использование |
|---|---|---|
| Adobe-Japan1 | 2007 | Японская коллекция символов Adobe. Основа для переключения вариантных глифов в коммерческих шрифтах |
| Hanyo-Denshi | 2010 | Программа Hanyo-Denshi Information Exchange Environment Development. Соответствует государственным символам вроде символов семейного реестра и Basic Resident Register |
| Moji_Joho | 2014 | Соответствует Платформе символьной информации (MJ). Используется с IPAmj Mincho. Дополнительные регистрации также в августе 2026 |
Документация Microsoft, например, даёт пример U+845B одного (葛), используемого в написании станции Ниси-Касай, и U+845B+U+E0100 (VS17), используемого в написании города Кацураги, Нара. Тот же 葛, но какой это глиф можно различить как данные.3
flowchart TB
accTitle: Пример различения одного и того же 葛 как данных через IVS
accDescr: 葛 как один U+845B используется в написании станции Ниси-Касай; последовательность U+845B, за которым следует VS17, используется в написании города Кацураги; какая последовательность относится к какому глифу, решает реестр IVD
seq1["Один U+845B"] --> gl1["Глиф, используемый в написании станции Ниси-Касай"]
seq2["U+845B + VS17"] --> gl2["Глиф, используемый в написании города Кацураги"]
ivd["IVD (реестр)"] -.-> gl1
ivd -.-> gl2
Рис. 5: Даже с одним и тем же 葛 наличие или отсутствие селектора позволяет различить, какой это глиф, как данные.
4.1. Поведение в среде, которая это не поддерживает
На стороне шрифта соответствие между IVS и глифом реализовано в таблице cmap OpenType (формат 14).5 Когда есть и поддерживающий шрифт (IPAmj Mincho и подобные), и поддерживающее приложение, появляется указанный глиф; когда нет — идёт так.
- Заданное правильное поведение: селектор игнорируется и отображается глиф по умолчанию базового символа (сам селектор невидим)
- Более старые приложения и некоторые стеки отрисовки: селектор трактуется как независимый неизвестный символ, и отображается лишний □
Иначе говоря, IVS спроектирован так, что «даже если деградирует, базовый символ читаем», но гарантия, что «всегда отобразится указанным глифом», зависит от среды получателя. Государственные системы учёта жителей и семейного реестра используют сочетание шрифта Платформы символьной информации плюс IVS, но если обычная бизнес-система принимает это спустя рукава, глиф упадёт где-то в отображении, печати или нисходящей системе.
flowchart TB
accTitle: Как отображаются данные с IVS
accDescr: Когда есть и поддерживающий шрифт, и поддерживающее приложение, отображается указанный глиф; когда нет, селектор игнорируется и показывается глиф по умолчанию базового символа; в более старых приложениях и некоторых стеках отрисовки селектор трактуется как неизвестный символ и отображается лишний □
ivs["База + селектор IVS"] --> env{"Поддерживающий шрифт + приложение?"}
env -->|Да| ok["Указанный глиф"]
env -->|Нет| other{"Как рисуется?"}
other -->|Игнорируется| ignore["Глиф по умолчанию"]
other -->|Старее / некоторые стеки| tofu["Лишний □"]
ignore -.-> spec["Заданное правильное"]
Рис. 6: IVS остаётся читаемым как базовый символ даже при деградации, но появится ли указанный глиф, зависит от среды получателя.
4.2. Оговорка реализации — «один символ» может занимать до четырёх кодовых единиц
Селекторы IVS начиная с U+E0100 — кодовые точки на дополнительной плоскости, поэтому в UTF-16 они всегда суррогатная пара (две кодовые единицы). Если базовый символ — кандзи дополнительной плоскости (например 𠮟 (U+20B9F), добавленный в JIS2004), одна база уже две кодовые единицы, и последовательность, которую пользователь узнаёт как «один символ», — до четырёх кодовых единиц в UTF-16 и до восьми байт в UTF-8.
"葛󠄀"в C# (葛+VS17) имеетstring.Length == 3.Substringи нарезка фиксированной длины рискуют отрезать базовый символ от селектора- Проверку числа символов и нарезку следует делать в единицах графемы (API вроде
StringInfo), а не в кодовых единицах - Для длины столбца БД (
nvarchar(n)SQL Server — в кодовых единицах UTF-16), если принимаете IVS, закладывайте в два–четыре раза видимое число символов - В поиске и сравнении наличие или отсутствие селектора делает другую строку. Попадает ли поиск «葛» в «葛+VS17» — то, что нужно решить как требование и реализовать
flowchart TB
accTitle: Один символ с IVS и кодовые единицы UTF-16
accDescr: Последовательность базового символа и идеографического селектора вариации, которую пользователь узнаёт как один символ, всегда суррогатная пара для селектора, а если базовый символ — кандзи дополнительной плоскости, ещё две кодовые единицы, максимум четыре кодовые единицы в UTF-16
one["Один видимый символ"] --> base["Базовый символ"]
one --> vs["Селектор вариации"]
base -.-> bnote["+2 если дополнительная"]
vs -.-> vnote["Всегда 2 кодовые единицы"]
base --> total["До 4 единиц UTF-16"]
vs --> total
total -.-> risk["Разрез при фиксированной нарезке"]
Рис. 7: Один символ с IVS может занимать до четырёх кодовых единиц в UTF-16; нарезка по кодовым единицам опасна.
5. Гайдзи (EUDC) — символы, которые отображаются только на том ПК
Гайдзи — механизм, в котором пользователь назначает собственный глиф кодовой точке в области частного использования Unicode (PUA: U+E000–U+F8FF и подобные). У кодовой точки области частного использования нет всемирно согласованного смысла; один и тот же U+E000 может быть назначен разному символу на каждом ПК и в каждой организации.6
В Windows глиф создают в Редакторе частных символов (eudcedit.exe), и он сохраняется в файле шрифта под названием eudc.tte. Этот файл устанавливается как скрытый шрифт и связывается с каждым шрифтом в реестре HKEY_CURRENT_USER\EUDC.7 В эпоху Shift_JIS (CP932) диапазон гайдзи был 0xF040–0xF9FC, и при преобразовании в Unicode он отображается на область частного использования.
Следствие этого механизма ясно.
- eudc.tte принадлежит тому ПК (тому пользователю) и не едет к другой стороне вместе с данными
- В момент передачи в почту, PDF, Веб или другую систему он становится □ или выглядит как чужой гайдзи другой стороны
- Если забыть мигрировать eudc.tte при миграции ОС или замене ПК, случается «символ, который отображался на старом ПК, не отображается»
Это суть второй консультации во вступлении.
flowchart TB
accTitle: Почему гайдзи отображаются только на том ПК
accDescr: Глиф, созданный в Редакторе частных символов, сохраняется в eudc.tte и связывается со шрифтами в реестре того ПК, поэтому если в почту, PDF или другую систему уходит только код области частного использования, он становится □ или выглядит как другой символ
edit["Создать глиф PUA"] --> tte["Сохранить в eudc.tte"]
edit -.-> editN["Редактор частных символов"]
tte --> reg["Сопоставление шрифтов реестра"]
reg --> local["Отображается на том ПК"]
tte -.-> stay["eudc.tte остаётся"]
send["Уходит только код PUA"] --> dest["Почта / PDF / другая система"]
dest --> broken["□ или неверный символ"]
local ~~~ send
Рис. 8: Глиф живёт в eudc.tte; в данных остаётся только номер области частного использования, поэтому гайдзи выглядят сломанными, как только покидают ПК.
5.1. Реалистичный ответ для системы, которая уже получила гайдзи
Проблема — когда в данных, унаследованных от унаследованной системы, гайдзи уже смешаны. Процедура, которую мы рекомендуем на миграционных работах, такая.
- Исследовать: просканировать базы и файлы регулярным выражением по области частного использования (U+E000–U+F8FF) и инвентаризировать используемые коды гайдзи и их количества. Собрать eudc.tte с ПК на каждой площадке и подтвердить глифы
- Опознать: для каждого гайдзи исследовать «можно ли представить как обычный символ Unicode», «можно ли представить через IVS», «есть ли соответствующий символ в Платформе символьной информации (MJ)», и построить таблицу соответствия символов-замен. На практике большинство случаев — просто то, что старая форма была сделана как гайдзи JIS
- Заменить: заменить данные по таблице соответствия. Только когда соответствующего символа действительно нет, оставить как изображение или приложить примечание к этой записи
- Отрезать: в новой системе отклонять ввод области частного использования в проверке и не создавать новые гайдзи
flowchart TB
accTitle: Процедура миграции данных, содержащих гайдзи
accDescr: Инвентаризируйте используемые гайдзи сканированием области частного использования и сбором eudc.tte, постройте таблицу соответствия символов-замен и замените, а в новой системе отклоняйте ввод области частного использования в проверке и не создавайте новые гайдзи
st1["Исследовать: сканировать PUA"] --> st2["Опознать: таблица замен"]
st2 --> st3["Заменить по таблице"]
st3 --> st4["Отрезать: никаких новых гайдзи"]
st1 -.-> tte["Собрать eudc.tte"]
st2 -.-> nomap["Нет карты: изображение или примечание"]
Рис. 9: Мигрируйте гайдзи в четыре стадии — исследовать, опознать, заменить и отрезать — и не создавайте новые гайдзи.
На государственной стороне направление то же: заявлена политика однозначно опознавать гайдзи, которые муниципалитеты создали самостоятельно (говорят, около двух миллионов символов по стране), относительно стандартных символов для административных дел, описанных ниже, и прекратить их использование.10 «Не увеличивать гайдзи; опознавать их относительно стандартизированного набора символов» становится устоявшимся шаблоном миграции и в государственном, и в частном секторе.
6. Государственная платформа символов — от унифицированных символов косэки к стандартным символам для административных дел
При проектировании системы, которая обрабатывает личные имена, знание государственной платформы символов становится материалом для решения «насколько далеко принимать».
| Название | Ответственный | Очерк |
|---|---|---|
| Унифицированные символы косэки | Министерство юстиции | Около 56 000 символов, организованных для компьютеризации семейных реестров. Ищутся на сайте Министерства юстиции8 |
| Унифицированные символы Juki-net | J-LIS (Japan Agency for Local Authority Information Systems) | Около 21 000 символов, используемых в Basic Resident Register Network |
| Платформа символьной информации (MJ) | Character Information Technology Promotion Council | Около 60 000 символов, используемых в административной работе, организованных. Управляются именами глиф-символ MJ; публикуются шрифт IPAmj Mincho и список символьной информации MJ. Организована как проект IPA и теперь передана совету9 |
| Стандартные символы для административных дел (MJ+) | Digital Agency | Набор символов, расширяющий Платформу символьной информации символами семейного реестра, которые нельзя опознать относительно MJ, и подобными. Личные имена и подобные в системах, соответствующих стандарту, используют этот набор; кодировка символов — JIS X 0221:202010 |
В муниципальных основных бизнес-системах (системах, соответствующих стандарту) в стандартной спецификации двухъярусная структура: использовать стандартные символы для административных дел для информационного взаимодействия личных имён и подобных и взаимодействовать с внешними системами, у которых нет единых правил взаимодействия, — смартфонами и подобными — в пределах JIS X 0213:2012.10 Сама структура «держать широкий набор символов внутри и обмениваться снаружи в диапазоне, который обычная среда может отобразить» — также ориентир для частных систем.
flowchart TB
accTitle: Двухъярусное взаимодействие системы, соответствующей стандарту
accDescr: Муниципальная система, соответствующая стандарту, использует стандартные символы для административных дел для информационного взаимодействия личных имён и подобных и взаимодействует с внешними системами вроде смартфонов, у которых нет единых правил взаимодействия, в пределах JIS X 0213:2012
sys["Муниципальная стандартная система"] --> renkei["Взаимодействие имён"]
sys --> gaibu["Внешние системы"]
renkei --> mjp["Стандартные адм. символы"]
mjp -.-> mjpN["Личные имена и т.д."]
gaibu --> jis["Пределы JIS X 0213:2012"]
gaibu -.-> sumaho["Нет правил (смартфон)"]
mjp -.-> naibu["Широкий набор внутри"]
Рис. 10: Двухъярусная структура: государственное взаимодействие использует стандартные символы для административных дел; внешнее взаимодействие без правил использует JIS X 0213:2012.
Как практическое руководство для обычной бизнес-системы рекомендуем следующее.
- Решите принимаемый набор символов и заявите его и в спецификации, и в проверке ввода. Например «пределы JIS X 0213:2012», «область частного использования и комбинирующие символы не допускаются», «IVS не принимается (или принимается, но отображение гарантируется только в среде IPAmj Mincho)»
- Не принимайте без ограничений. Проект «это Unicode, значит всё можно» сломается где-то в отображении, печати или взаимодействии
- Заранее решите операцию для символов вне диапазона. Правило подстановки альтернативного представления (новая форма, катакана) и формулировка, которую объясняете человеку, сами по себе спецификация системы
- Когда у нисходящей системы вроде государственной или финансовой есть правило набора символов, берите его как авторитетное и выравнивайтесь
flowchart TB
accTitle: Проектирование и эксплуатация принимаемого набора символов
accDescr: Решите принимаемый набор символов и заявите его и в спецификации, и в проверке ввода; принимайте символы в диапазоне; для символов вне диапазона решите операцию, включая правило подстановки альтернативного представления и формулировку, которую объясняете человеку
decide["Решить принимаемый набор символов"] --> spec["Заявить в спецификации"]
decide --> valid["Заявить в проверке ввода"]
valid --> range{"В диапазоне?"}
range -->|Да| ok["Принять"]
range -->|Нет| alt["Подставить альтернативное представление"]
alt -.-> word["Формулировка, которую объясняете человеку, тоже спецификация"]
Рис. 11: Заявите принимаемый набор символов и в спецификации, и в проверке ввода и решите также операцию вне диапазона.
7. Выбор и встраивание шрифтов — выравнивание экрана и формы
7.1. Характер обычных шрифтов
| Шрифт | Покрытие | Характер и где использовать |
|---|---|---|
| MS Gothic / MS Mincho | Стандарт Windows | Старая рука, рассчитанная на экраны низкого разрешения. Глиф по умолчанию на базе JIS20042. Всё ещё в службе для поддержания совместимости с унаследованными формами |
| Meiryo | С Vista | Современный экранный шрифт, исходящий из ClearType. Появился одновременно с миграцией JIS2004 поколения Vista1 |
| Yu Gothic / Yu Mincho | С Windows 8.1 | Семейство, поставляемое и на Windows, и на macOS, что облегчает выравнивание вида документов |
| BIZ UD Gothic / BIZ UD Mincho | С Windows 10 1809 | Универсальный дизайн Morisawa. Первый кандидат на работах, где важна читаемость формы и экрана14 |
| Noto Sans JP | Устанавливается отдельно | Предоставляется как открытый исходный код и легко комплектуется на сервере или в среде Linux и доставляется в Веб |
В выборе важнее не предпочтение начертания, а есть ли этот шрифт в каждой среде, задействованной в отображении, печати и генерации PDF. Японские дополнительные шрифты на Windows 10/11 (BIZ UD и подобные) иногда отсутствуют в зависимости от конфигурации, и в конфигурации, которая генерирует PDF на стороне сервера, наличие или отсутствие шрифта на сервере имеет прямое влияние.
flowchart TB
accTitle: Среды, которые нужно подтвердить при выборе шрифта
accDescr: При выборе шрифта важнее не предпочтение начертания, а есть ли этот шрифт в каждой среде, задействованной в отображении, печати и генерации PDF; конфигурация дополнительных шрифтов и наличие или отсутствие шрифта на сервере имеют прямое влияние
cand["Шрифт-кандидат"] --> exist["На каждой среде?"]
exist --> scr["Среда отображения"]
exist --> more{"Сервер печати или PDF?"}
more --> prn["Среда печати"]
more --> srv["Сервер генерации PDF"]
scr -.-> hojo["Дополнительный шрифт?"]
hojo -.-> hojoN["Может отсутствовать"]
srv -.-> eikyo["Шрифт на сервере важен"]
Рис. 12: Выбирайте шрифт меньше по предпочтению начертания, чем по тому, есть ли он в каждой среде отображения, печати и генерации PDF.
7.2. Основы проектирования форм — выровнять и встроить
- Укажите один и тот же шрифт на экране и на форме. Если шрифты различаются, те же данные могут выглядеть как другой глиф, и вы получите жалобу из вступления. Конфигурацию вроде «Meiryo на экране, MS Mincho на форме» стоит хотя бы проверить на разницу глифа на 168 символах JIS2004
- Встройте шрифт в PDF. Если не встроить, сторона просмотра подставно рисует шрифтом, который у неё есть, и может смениться не только глиф, но и макет
- Разрешено ли встраивание, определяет лицензия. Шрифт OpenType объявляет разрешения на встраивание в поле
fsType(Installable / Restricted / Preview & Print / Editable, no-subsetting и подобные), и нельзя встраивать шрифт, чьё встраивание не лицензировано.11 Для коммерческого шрифта требуется подтверждение договора - Сделайте подмножественное встраивание базой. Если встроить только глифы использованных символов, не нужно брать на себя целый японский шрифт (от нескольких МБ до десятков МБ)
- Если есть требование долгосрочного хранения — PDF/A. PDF/A (ISO 19005) — стандарт, который завершает ресурсы, нужные для отображения, внутри файла, и встраивание шрифта требуется.12 Это также самый надёжный способ предотвратить «через десять лет открыл — глифы сменились»
flowchart TB
accTitle: Поток решения о встраивании шрифта
accDescr: Перед встраиванием шрифта в PDF подтвердите лицензию встраивания fsType; если лицензировано, сделайте подмножественное встраивание базой; если есть требование долгосрочного хранения, рассмотрите PDF/A, который требует встраивания
emb["Встроить шрифт в PDF"] --> lic{"Встраивание лицензировано fsType?"}
lic -->|Лицензировано| sub["Подмножественное встраивание — база"]
lic -->|Не лицензировано| ng["Встраивать нельзя"]
sub -.-> gly["Только глифы использованных символов"]
sub -->|Требование долгосрочного хранения| pdfa["Рассмотреть PDF/A"]
pdfa -.-> must["Встраивание шрифта требуется"]
Рис. 13: Встраивание исходит из подтверждения лицензии fsType; подмножественное встраивание и PDF/A — база.
Как выбрать средство реализации для печати и вывода PDF подробно разобрано в «Печать и вывод PDF в Windows-бизнес-приложениях».
8. Связывание шрифтов и запасной путь — явление «подмешивается другой шрифт»
Символ, для которого у указанного шрифта нет глифа, отображается не как ничто; подставная отрисовка другим шрифтом — поведение по умолчанию современных стеков отрисовки. В GDI это делает «связывание шрифтов», определённое в реестре (FontLink\SystemLink); в DirectWrite, WPF и браузерах — «запасной путь шрифта».15
flowchart TB
accTitle: Поток связывания шрифтов и запасного пути
accDescr: Если у указанного шрифта есть глиф, отображается как есть; если нет, рисуется подставно шрифтом связи или запасного пути; если глифа нет нигде, становится □, но данные часто ещё живы
disp["Отобразить символ"] --> has{"Есть глиф у указанного шрифта?"}
has -->|Да| draw["Отобразить указанным шрифтом"]
has -->|Нет| fb{"Есть в цели связи или запасного пути?"}
fb -->|Да| alt["Подставно нарисовать другим шрифтом"]
alt -.-> mixed["Причина ощущения смешанного начертания"]
fb -->|Нет| tofu["Отображается □ (тофу)"]
tofu -.-> alive["Данные часто ещё живы"]
Рис. 14: □ — след сбоя запасного пути; удаётся ли подставная отрисовка — развилка между «смешанным» и «тофу».
Знание этого механизма позволяет объяснить следующие частые случаи.
- Ощущение начертания различается между латиницей и японским: потому что сначала указан латинский шрифт, только японская часть рисуется связанным или запасным японским шрифтом
- Только кандзи в японском предложении становятся глифом в китайском стиле: цель запасного пути разрешилась в китайский шрифт. Легко случается на веб-странице или в приложении, которое не передаёт правильно языковую информацию (атрибут lang или локаль)
- Появляется тофу (□): ни у указанного шрифта, ни у цели запасного пути нет глифа. Иначе говоря, □ — «след сбоя запасного пути», и данные часто ещё живы
Запасной путь — механизм помощи; он не заменяет выбор правильного шрифта с самого начала.15 В бизнес-приложении здоровая позиция — «на основных путях отображения и печати завершать только спроектированными шрифтами; запасной путь — страховка на неожиданные символы». О мышлении выбора шрифта в многоязычном интерфейсе см. также «Интернационализация приложений WinForms/WPF».
9. Чек-лист реализации для бизнес-приложений
Наконец, пункты, которые нужно подтвердить на каждом слое от ввода до взаимодействия, сведены в таблицу.
| Слой | Типичная авария | Пункты проектирования и реализации |
|---|---|---|
| Ввод | Зависящие от среды символы, символы с IVS и символы области частного использования приходят из IME | Решите принимаемый набор символов и проверяйте. Вне диапазона руководство (предложение альтернативного представления), а не ошибка, держит работу у стойки в движении |
| Нормализация | Непреднамеренные преобразования вроде NFKC, превращающего ㈱ в (株), унификации полной и половинной ширины, ① в 1. Даже NFC заменяет CJK Compatibility Ideograph (напр. U+FA19 神) на Unified Ideograph U+795E | Не применяйте NFKC к личным именам и адресам. Ограничьте нормализацию применением (генерация ключа поиска и подобное) и храните оригинал как введённый13 |
| Хранение | Нехватка длины столбца из-за суррогатных пар и IVS; усечение по кодовой единице | Храните в UTF-8/UTF-16 и дайте запас длины столбца в кодовых единицах. Нарезайте в единицах графемы |
| Отображение | □ потому что у шрифта нет глифа; глиф меняется через запасной путь | Явно укажите шрифт, который может отобразить целевой набор символов, и подтвердите стандартное покрытие на целевой ОС |
| Печать и PDF | Разница глифа между экраном и формой; подставная отрисовка на стороне просмотра | Выровняйте шрифт на экране и на форме и подмножественно встройте в PDF после подтверждения лицензии11 |
| Взаимодействие с другой системой | Дополнительные кандзи JIS X 0213, IVS и гайдзи становятся ? или 〓 при преобразовании Shift_JIS (CP932) |
Заявите кодировку символов и набор символов в спецификации взаимодействия. Если остаётся взаимодействие CP932, реализуйте обнаружение неконвертируемых символов и правило подстановки |
Нормализация в особенности — ловушка, которая есть сама тема этой статьи: процесс, применённый «из добрых побуждений», который давит различие вариантных символов и полной ширины против половинной. Оригинал как есть; обработка на копии — принцип. Аварии кодировки символов во взаимодействии CSV подробно разобраны в «CSV — не «просто текст»».
flowchart TB
accTitle: Оригинал как есть; обработка на копии
accDescr: Храните введённую строку как есть как оригинал; применяйте нормализацию к копии, ограниченной применением вроде генерации ключа поиска; применение NFKC к оригиналу теряет различие вариантных символов и полной ширины против половинной
input["Введённая строка"] --> orig["Оригинал: хранить как введённый"]
input --> copy["Копия: нормализовать, ограниченно применением"]
copy -.-> use["Генерация ключа поиска и подобное"]
orig -.-> ng["NFKC на оригинале давит различия"]
Рис. 15: Ограничьте нормализацию применением и применяйте к копии; храните оригинал как введённый.
10. Итог
- Сначала делите проблемы символов на «слой данных (кодировка символов)» и «слой внешнего вида (шрифты)». � — знак аварии на слое данных, □ — на слое внешнего вида.
- JIS X 0213:2004 сменил образцовые глифы 168 символов, и Windows имеет глифы JIS2004 по умолчанию начиная с Vista. То, что 葛, 辻 и 飴 выглядят по-разному в зависимости от среды, — история шрифтов, а не порча данных.
- Стандартное средство зафиксировать глиф как данные — IVS, но без поддерживающего шрифта и поддерживающего приложения он падает к глифу по умолчанию. Не забывайте влияние на реализацию, что один символ может занимать до четырёх кодовых единиц UTF-16.
- Гайдзи (EUDC) — актив, специфичный для того ПК, и не может ехать вместе с данными. Реалистичный ответ — инвентаризировать при миграции, заменить по таблице соответствия к обычным символам или IVS и прекратить создавать новые.
- Система, которая обрабатывает личные имена, решает принимаемый набор символов и заявляет его. Государство стандартизируется к стандартным символам для административных дел на фундаменте унифицированных символов косэки и Платформы символьной информации, и системе, которая взаимодействует, нужно следовать этому движению.
- Для форм и PDF база — «выровнять шрифт с экраном, подтвердить лицензию и встроить». Для долгосрочного хранения рассмотрите PDF/A.
- Нормализация NFKC, нарезка по кодовой единице и преобразование CP932 — три точки, которые тихо ломают вариантные символы и гайдзи. Сделайте хранение оригинала и обработку в единицах графемы принципом.
В следующий раз, когда скажут «символ другой», сначала переформулируйте вопрос так. Кодовые точки те же или разные? Если те же — проблема шрифта; если разные — проблема данных. Этот один ход не даёт взять неверную точку входа расследования.
flowchart TB
accTitle: Первый вопрос, который решает точку входа расследования
accDescr: Когда говорят, что символ другой, сначала сравните, те же кодовые точки или разные; если те же, начинайте расследование как проблему шрифта, если разные — как проблему данных
said["Сказали, что символ другой"] --> cmp{"Кодовые точки те же?"}
cmp -->|Те же| fontp["Проблема шрифта"]
cmp -->|Разные| datap["Проблема данных"]
Рис. 16: Если кодовые точки те же, начинайте расследование как проблему шрифта; если разные — как проблему данных.
Похожие статьи
- Введение в кодировки текста в Windows — искажение кодировки (mojibake), возникающее при интеграции с Linux
- Кодировки текста и символы перевода строки в Windows — основы искажения кодировки и CRLF/LF
- Печать и вывод PDF в Windows-бизнес-приложениях — выбор между System.Drawing.Printing, WPF и библиотеками отчётов
- Интернационализация приложений WinForms/WPF — resx, сателлитные сборки и переключение культуры на практике
- CSV — не «просто текст»: практика работы с CSV в бизнес-приложениях на C# (кодировки, совместимость с Excel, защита от инъекций)
- Введение в доступность приложений Windows — подготовка к UI Automation и требованиям разумного приспособления
Смежные области консультирования
KomuraSoft LLC занимается проектированием и расследованием вокруг символов в бизнес-системах. От изоляции причины симптомов вроде «символ различается на экране и на форме» или «после миграции личное имя стало □» через инвентаризацию гайдзи и построение таблицы символов-замен при миграции с унаследованной системы, проектирование принимаемого набора символов системы, которая обрабатывает личные имена, и ревью конфигурации встраивания шрифтов форм и PDF мы покрываем и слой кода, и слой шрифта.
- Разработка Windows-приложений
- Использование и миграция существующих активов
- Техническая консультация и ревью проекта
- Связаться с нами
Справочные ссылки
-
Morisawa Inc., JIS X 0213:2004 (JIS2004) | Font glossary. О том, что образцовые глифы 168 кандзи были пересмотрены в JIS X 0213:2004, следуя Hyogai Kanji Jitaihyo, к печатным стандартным формам (так называемым формам словаря Канси); и о том, что шрифты, способные к JIS2004, были включены как стандарт в Windows Vista. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, MS Gothic font family. О том, что глиф по умолчанию семейства MS Gothic на базе JIS2004, и о возможности доступа к унаследованным глифам JIS90 через возможность OpenType ‘jp90’. ↩ ↩2 ↩3
-
Microsoft Learn, The Unicode standard. О том, что последовательность вариации состоит из базового символа плюс идеографический селектор вариации (VS1–VS256, U+FE00–U+FE0F и U+E0100–U+E01EF); о примере различения U+845B 葛 от U+845B+U+E0100 (VS17) (станция Ниси-Касай и город Кацураги); и о том, что для отображения требуется поддерживающий шрифт. ↩ ↩2 ↩3
-
Unicode Consortium, Ideographic Variation Database. Реестр IVS на базе UTS #37. О том, что зарегистрированы коллекции вроде Adobe-Japan1 (2007), Hanyo-Denshi (2010) и Moji_Joho (2014), и о том, что дополнительные регистрации в коллекцию Moji_Joho также сделаны в издании августа 2026. ↩ ↩2
-
Microsoft Learn, cmap — Character to Glyph Index Mapping Table (OpenType spec). О том, что шрифт OpenType реализует Unicode Variation Sequences в подтаблице cmap формата 14; о различении UVS по умолчанию и не по умолчанию; и о примерах использования в шрифтах, способных к JIS2004. ↩ ↩2
-
Microsoft Learn, End-User-Defined and Private Use Area Characters. О том, что гайдзи (EUDC) и символы области частного использования (PUA) определяются независимо пользователем или организацией, и о том, что одна кодовая точка может иметь разное назначение — и сталкиваться — в зависимости от компьютера. ↩ ↩2
-
Microsoft Learn, Character Sets and Fonts. О том, что PUA (U+E000–U+F8FF и подобные) используется для целей Unicode EUDC; о создании глифа в Редакторе частных символов; и о том, что шрифт EUDC скрыто устанавливается как файл .tte и связывается со шрифтами в реестре HKEY_CURRENT_USER\EUDC. ↩ ↩2
-
Ministry of Justice, Koseki Unified Character Information — search-condition input. Официальный поисковый сайт унифицированных символов косэки, предоставляемый Министерством юстиции. О возможности искать глифы, чтения и связанную информацию символов, используемых в семейных реестрах. ↩ ↩2
-
Character Information Technology Promotion Council, Character Information Platform project. О том, что Платформа символьной информации (глифы символов MJ, список символьной информации MJ и шрифт IPAmj Mincho), организованная IPA при поддержке Министерства экономики, торговли и промышленности и других и охватывающая около 60 000 кандзи, используемых в административной работе, теперь передана совету и публикуется. ↩ ↩2
-
Digital Agency, Report of the Study Group on the Operation of Character Requirements in Local-Government Information Systems (July 2024). О том, что гайдзи, используемые в муниципалитетах, называют около двух миллионов символов; о том, что «стандартные символы для административных дел» (обычно MJ+), расширение Платформы символьной информации, — набор символов для личных имён и подобных в системах, соответствующих стандарту, с кодировкой JIS X 0221:2020; об использовании стандартных символов для административных дел для информационного взаимодействия личных имён и подобных и JIS X 0213:2012 для взаимодействия со смартфонами и подобными; и о политике однозначно опознавать обычные гайдзи относительно стандартных символов для административных дел и не использовать их. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, OS/2 — OS/2 and Windows Metrics (OpenType spec). О том, что поле fsType шрифта определяет лицензию встраивания (Installable / Restricted License / Preview & Print / Editable, бит no-subsetting и подобные), и о том, что приложению не разрешено встраивать шрифт, чьё встраивание не лицензировано. ↩ ↩2 ↩3
-
PDF Association, PDF/A Basics. О том, что PDF/A для долгосрочного хранения (ISO 19005) требует, чтобы элементы, нужные для отображения документа, были включены внутри файла, со встраиванием шрифта как типичным требуемым примером. ↩ ↩2
-
Microsoft Learn, Using Unicode Normalization to Represent Strings. О четырёх формах нормализации Unicode NFC/NFD/NFKC/NFKD; и о том, что формы KC/KD унифицируют символы совместимости вроде символов полной и половинной ширины и теряют информацию, поэтому в целом не подходят как каноническая хранимая форма строки. ↩ ↩2
-
Microsoft Learn, BIZ UDGothic font family. О том, что шрифт универсального дизайна Morisawa BIZ UD Gothic включён как японский дополнительный шрифт начиная с Windows 10 версии 1809. ↩
-
Microsoft Learn, Fonts (Globalization documentation). О механизме запасного пути шрифта; о связывании шрифтов GDI (реестр FontLink\SystemLink); о смысле глифа по умолчанию (тофу); и о том, что связывание шрифтов не заменяет выбор правильного шрифта. ↩ ↩2
Похожие статьи
Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.
Приложения, которые ломаются после выхода из сна — как работают события питания Windows и как строить бизнес-приложения, которые это переживают
Открыли ноутбук — и соединения бизнес-приложения мертвы: причина в проекте, который не учитывал сон. Статья разбирает поток уведомлений W...
Введение в доступность приложений Windows — подготовка к UI Automation и требованиям разумного приспособления
На фоне поправки к Закону об устранении дискриминации в отношении лиц с инвалидностью, вступившей в силу в апреле 2024 года, статья с пра...
Кодировки текста и символы перевода строки в Windows — основы искажения кодировки и CRLF/LF
Разбираем часто путаемые в Windows Shift_JIS / UTF-8 / UTF-16, причины возникновения искажения кодировки и разницу между CRLF и LF в удоб...
Введение в кодировки текста в Windows — искажение кодировки (mojibake), возникающее при интеграции с Linux
Разбираем практические причины искажения кодировки в Windows — через различия между CP932, UTF-8, UTF-16, BOM, кодовыми страницами, Power...
Глубины виртуализации Windows (часть 3) — виртуальные машины, которые загружаются за секунды: почему WSL2, Windows Sandbox и контейнеры такие лёгкие
Почему WSL2 и Windows Sandbox стартуют за секунды и ощущаются такими лёгкими? Статья разбирает механизмы — от динамического базового обра...
Связанные темы
Эти страницы показывают тему статьи в более широком контексте услуг и решений.
Технические темы Windows
Раздел о разработке Windows, расследовании сбоев и использовании существующих активов.
Услуги по этой теме
Статья напрямую связана со следующими услугами.
Разработка приложений для Windows
Бизнес-приложения, интеграция оборудования и средства связи — от требований до разработки.
Частые вопросы
Вопросы, которые часто возникают при консультациях по теме статьи.
- Почему один и тот же символ 葛 выглядит по-разному в зависимости от ПК или печатной формы?
- Скорее это разница глифов шрифта, а не искажение кодировки. JIS X 0213:2004 (JIS2004) пересмотрел образцовые глифы 168 кандзи к печатным стандартным формам, и Windows тоже сделал глифы JIS2004 умолчанием в MS Gothic / MS Mincho и других начиная с Vista. 葛, 辻, 飴 и подобные — типичные примеры: кодовая точка Unicode (данные) остаётся той же, а меняется только глиф, который держит шрифт (внешний вид). Сравните данные — они совпадают; расхождение формы между образом формы эпохи XP и экраном нового ПК — заданное поведение. Если хотите выровнять и глифы, используйте один и тот же шрифт на экране и на форме либо укажите глиф идеографическим селектором вариации.
- Если использовать идеографические селекторы вариации (IVS), решит ли это все проблемы глифов в личных именах?
- Нет. IVS — механизм, который ставит селектор начиная с U+E0100 сразу после базового символа, чтобы указать глиф как данные, и указанный глиф отображается только когда есть и поддерживающий шрифт вроде IPAmj Mincho, и поддерживающее приложение. В неподдерживающей среде заданное поведение — селектор игнорируется и показывается глиф по умолчанию базового символа; в некоторых средах селектор может также появиться как □. Далее, один символ с IVS может занимать до четырёх кодовых единиц в UTF-16, что влияет на подсчёт символов, нарезку и проектирование длин столбцов БД. Если вводите это, подтвердите объём поддержки через отображение, печать и нисходящие системы, прежде чем пользоваться.
- Может ли символ, зарегистрированный как гайдзи (EUDC), отображаться на другом ПК или в PDF?
- В принципе нет. Гайдзи — механизм, в котором пользователь регистрирует глиф в файл eudc.tte этого ПК на кодовой точке в области частного использования Unicode (начиная с U+E000); та же кодовая точка не определена или является другим глифом на другом ПК. Судьба передачи его в почту, PDF или другую систему поэтому в том, что он становится □ или выглядит как другой символ. Если вы уже унаследовали данные, содержащие гайдзи, реалистичный путь при миграции — инвентаризировать использования области частного использования, построить таблицу соответствия к обычным символам Unicode или идеографическим селекторам вариации и заменить. В новой системе не следует создавать новые гайдзи.
- Насколько далеко бизнес-система должна принимать символы в личных именах?
- Первое — «решить принимаемый набор символов и заявить его как спецификацию». В семейных реестрах около 56 000 унифицированных символов косэки, и системы, соответствующие государственному стандарту, движутся к использованию стандартных символов для административных дел, расширения Платформы символьной информации — но обычная бизнес-система не обязана принимать тот же уровень без ограничений. Реалистичный проект — решить диапазон вроде «в пределах JIS X 0213» или «не принимать идеографические селекторы вариации и область частного использования», проверять на вводе и обрабатывать случаи вне диапазона предупреждением или альтернативным представлением. Только системы, которые взаимодействуют с государственными системами или муниципалитетами, должны следовать движению стандартных символов для административных дел и требованиям взаимодействия на базе JIS X 0221.
- Как сделать так, чтобы форма или PDF показывали те же символы, что и экран?
- База — указать один и тот же шрифт на экране и на форме и встроить шрифт в PDF. Если шрифты различаются, те же данные могут сменить глиф; если на просматривающем ПК нет шрифта, для отрисовки используется подставной шрифт и внешний вид ломается. Разрешено ли встраивание, определяет лицензия шрифта (OpenType fsType), поэтому подтверждайте её, а не оставляйте библиотеке отчётов. Подмножественное встраивание, которое встраивает только использованные символы, также держит размер файла ниже. Если долгосрочное хранение — требование, рассмотрите PDF/A, который требует встраивания шрифта.
Об авторе
Страница с профилем автора статьи.
Го Комура
Представитель KomuraSoft LLC
Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.