更新履歴(5件・最終更新 2026年09月06日)
この記事に加えた変更の記録です。アーカイブした更新前のバージョンは、DOI付きの固定URLから読めます。
- 技術的な主張と条件はそのままに、文字データと見た目の切り分けを冒頭で示し、症状別の読み方、IVSの実装上の注意、外字の移行、受け入れ文字集合、帳票・PDFのフォント設計を小見出しで追いやすく整理した。
- 知識マップの関係を総点検し、説明文と食い違っていた関係(向きの逆転・過剰な一般化・述語の取り違え)を修正しました。本文の説明は変えていません。
- 知識マップの関係を総点検し、説明文と食い違っていた関係(向きの逆転・過剰な一般化・述語の取り違え)を修正しました。本文の説明は変えていません。
- 知識マップでJIS2004字形切り替えの設定手段をcmap format 14からOpenTypeの'jp90'フィーチャに改めました。IVSの字形指定を担うcmap format 14とは別の仕組みのためです。本文の説明は変えていません。
- 仕組みの説明を図で追えるよう、Mermaid図を16点追加しました。冒頭の2つの相談の正体、�と□による症状の切り分け、MSゴシックの既定字形とjp90フィーチャ、同じ符号位置でもフォントで字形が変わる仕組み、IVSで同じ葛をデータで区別する例、IVS付きデータの表示のされ方とコード単位数、外字がそのPCでしか出ない理由と移行手順、行政の文字連携の2段構え、受け入れ文字集合の設計と運用、フォントの選定と埋め込みの判断、フォントフォールバックの流れ、原本保存と正規化の使い分け、調査の入口の決め方を図にしています。本文の文章とコード、参考リンクは変えていません。
- 初版公開
この記事を引用する(DOI: 10.5281/zenodo.22054267)
この記事はZenodoにアーカイブされています。常に最新版へ解決されるDOIと、いま表示している版に固定されたDOIの両方を下に示します。
小村 豪(2026)「日本語フォントと文字の落とし穴 ── JIS2004・異体字セレクタ・外字を業務アプリでどう扱うか」合同会社小村ソフト. https://doi.org/10.5281/zenodo.22054267 https://comcomponent.com/blog/japanese-fonts-jis2004-ivs-gaiji-business-apps/
- DOI(最新版)
- 10.5281/zenodo.22054267
- DOI(この版)
- 10.5281/zenodo.22524448
「同じ氏名なのに、画面と帳票で字の形が違う」「PCを入れ替えたら、以前は出ていた字が□になった」──日本語を扱う業務システムでは、こうした相談が起きます。
最初に確かめるのは、文字のデータが変わったのか、それとも同じデータの見た目だけが変わったのかです。 ここを分けないまま「文字化け」として直そうとすると、調査の入口を間違えます。
この記事では、顧客名簿の「葛」が画面と印刷した帳票で違って見える相談と、役所へ出す書類の氏名がPCの入れ替え後に表示できなくなった相談を入口に考えます。
ここで取り上げる2つの相談は、エンコーディングの不一致で起きる文字化けとは別の問題です。1つ目はデータが1ビットも変わっていないのに見た目だけが変わったケース、2つ目はそのPCにしか存在しない「外字」が失われたケースです。
flowchart TB
accTitle: よくある2つの相談の正体
accDescr: 画面と帳票で葛の形が違う相談はデータが変わらないまま見た目だけが変わったもので、PCを入れ替えたら字が□になった相談はそのPCにしか存在しない外字が失われたもので、どちらもエンコーディング不一致の文字化けとは別の問題である
c1["相談1:画面と帳票で形が違う"] --> r1["データは変わらず見た目だけ変化"]
c2["相談2:入れ替えたら□になった"] --> r2["そのPCだけの外字が失われた"]
r1 --> diff["エンコーディングの文字化けとは別問題"]
r2 --> diff
図1: 「文字化け」と呼ばれがちな2つの相談は、どちらもエンコーディング不一致とは別の問題。
文字コード(データの層)とフォント(見た目の層)を分けて考えれば、日本語の文字トラブルの大半は整理できます。 本記事は業務システムの開発者と情シス担当者に向けて、症状の切り分けから、JIS2004・IVS・外字の仕組み、受け入れる文字の範囲、帳票・PDFの設計までを順に説明します。
Shift_JISとUTF-8の変換で起きる「化け」そのものは既存記事で扱っているため、本記事は「コードは正しく往復しているのに、見た目や表示可否がずれる」問題に集中します。
1. まず結論
「どのバイト列を保存するか」はデータ設計の問題、「それがどう見えるか」はフォント設計の問題です。 対応を決めるときは、次の3つを分けて考えます。
まず、データが同じかを確かめる
「文字化け」はバイト列の解釈を誤るデータ層の問題です。一方、同じUnicodeの符号位置でも、フォントが違えば字形は変わります。JIS2004で「葛」「辻」「飴」など168字の例示字形が変わり、WindowsのMSゴシック/MS明朝もVista以降はJIS2004字形が既定になりました。12
字形の指定と、外字の持ち運びを混同しない
字形をデータとして指定する標準的な手段がIVSです。ただし、対応フォントと対応アプリが必要で、非対応環境ではセレクタを無視して基底文字の既定字形を表示するのが正しい挙動です。見かけの1文字がUTF-16で最大4コード単位になるため、表示だけでなく文字数や切り出しにも影響します。34
外字(EUDC)はこれとは別で、私用領域の番号に全世界共通の意味がありません。eudc.tteにある字形はデータと一緒には相手へ渡らないため、移行時には調査と代替文字への対応付けが必要です。56
受け入れる文字と、出力する環境を仕様にする
氏名を扱うシステムは、受け入れる文字集合を決めて明示します。行政との連携では、戸籍統一文字や文字情報基盤を土台にした行政事務標準文字の動向も確認します。789 帳票・PDFは、画面とフォントを揃え、ライセンスを確認して埋め込むのが基本です。長期保存にはPDF/Aを検討します。1011
また、氏名の原本にNFKC正規化を安易にかけてはいけません。 全角半角や互換文字の置き換えで、保持すべき区別が失われるためです。12
症状・目的から読む場所を選ぶ
| 困っていること・決めたいこと | 最初に確認すること | 読む場所 |
|---|---|---|
| 文字化けなのか、字形の違いなのか分からない | コードポイントが同じか。「�」と「□」の違いは何か | 2章: データと見た目 |
| 移行前後や画面・帳票で「葛」「辻」などの形が違う | JIS90とJIS2004の字形差、使用フォント | 3章: JIS2004、7章: 帳票・PDF |
| 氏名の字形までデータで区別したい | IVSへの対応が表示・印刷・連携先まで揃うか | 4章: IVS、4.2節: 実装への影響 |
| 古いPCでしか出ない文字がある | 私用領域の使用箇所と、元の外字フォント | 5章: 外字、5.1節: 移行手順 |
| 氏名をどこまで受け入れるか決めたい | 連携先の規定と、範囲外の文字の扱い | 6章: 文字集合の設計 |
| 一部だけ書体が変わる、または□になる | 指定フォントとフォールバック先に字形があるか | 8章: フォールバック |
| 実装や移行の抜け漏れを確認したい | 入力・正規化・保存・表示・印刷・連携の各層 | 9章: チェックリスト |
全体を理解する場合は2章から順に、目の前の症状を調べる場合は表の該当する節から読めます。対策を実装するときは、最後に9章で他の層への影響も確認してください。
図の実線は常に成り立つ関係、破線は条件付きの関係です(成立条件は詳細ページの各関係の説明に記載)。関係すべての一覧(全14件、根拠・確度つき)と主要概念の定義は知識マップ詳細ページにまとめています。データ: JSON-LD / Turtle
2. データと見た目を分けて考える ── 符号位置とグリフ
番号と、描かれる形は別のもの
Unicodeでは、文字は符号位置(コードポイント)という番号で表されます。「葛」はU+845Bであり、この番号はどのPCでも同じです。
一方、その番号を画面や紙にどう描くかは、フォントが持つグリフ(字形)が決めます。同じU+845Bでも、フォントAとフォントBで細部の形が違うのは正常な動作です。
症状から、調べる層を分ける
この2層を前提にすると、現場の症状は次のように切り分けられます。
| 層 | 起きる事故 | 代表的な症状 | 主な対処 |
|---|---|---|---|
| データ層(文字コード) | エンコーディングの解釈ミス、変換での欠落 | 「縺ッ」のような化け、?や〓への置換、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文字コード入門 - Linux連携で起きる文字化け」と「Windowsの文字コードと改行コード - 文字化けとCRLF/LFの基本」で扱っています。以降は見た目層と、その境界で起きる問題です。
3. JIS90からJIS2004へ ── 同じコードのまま字形が変わった
冒頭の「画面と帳票で『葛』の形が違う」の正体は、多くの場合ここにあります。
変わったもの: フォントの既定字形
2000年に国語審議会が答申した「表外漢字字体表」を受けて、2004年改正のJIS X 0213:2004(通称JIS2004)では、168字の漢字の例示字形が、いわゆる康熙字典体に近い印刷標準字体に改められました。「葛」「辻」「飴」「芦」「溢」「餅」などが代表例です。1
Windowsはこれに合わせて、Windows Vista以降のMSゴシック/MS明朝(および新設のメイリオ)でJIS2004字形を既定にしました。現在のMSゴシックも既定字形はJIS2004ベースで、OpenTypeのjp90フィーチャ経由でJIS90時代の字形にアクセスできる、という構成です。21
flowchart TB
accTitle: 現在のMSゴシックの字形の構成
accDescr: Vista以降のMSゴシックはJIS2004字形を既定とし、OpenTypeのjp90フィーチャを経由するとJIS90時代の字形にアクセスできる構成になっている
msg["MSゴシック(Vista以降)"] --> def["既定字形:JIS2004ベース"]
msg --> feat["jp90フィーチャ経由"]
feat --> old["JIS90時代の字形"]
図3: 現在のMSゴシックはJIS2004字形が既定で、jp90フィーチャでJIS90字形に切り替えられる。
変わらなかったもの: 文字のコードポイント
ここで重要なのは、変わったのはフォントだけで、データは何も変わっていないことです。
- 「葛」の符号位置はXPでもWindows 11でもU+845Bのままです
- XP(JIS90字形)では勹の中を「ヒ」に簡略化した形、Vista以降(JIS2004字形)では中に「人」まで書く形で表示されます
- したがって、旧システムで印刷した帳票のスキャン画像と、新PCの画面表示で字の形が食い違います。データ比較では完全に一致します
「辻」のしんにょうの点が1つか2つか、「飴」の食偏の形なども同様です。この歴史を知らないと、「移行でデータが壊れた」という誤った方向に調査が進みがちです。
調べる順序は、移行前後のコードポイントを比較する → 一致していればフォントの字形差を疑うです。見た目が違うという理由だけで、データが壊れたと判断しないでください。
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の登録で決まる
どの「基底文字+セレクタ」の並びがどの字形を指すかは、Unicodeコンソーシアムが管理するIVD(Ideographic Variation Database)という登録簿で決まります。
主なコレクションは次のとおりです。13
| コレクション | 登録 | 由来・用途 |
|---|---|---|
| Adobe-Japan1 | 2007年 | Adobeの日本語文字コレクション。商用フォントの異体字切り替えの土台 |
| Hanyo-Denshi(汎用電子) | 2010年 | 汎用電子情報交換環境整備プログラム。戸籍・住基などの行政文字に対応 |
| Moji_Joho | 2014年 | 文字情報基盤(MJ)に対応。IPAmj明朝で利用。2026年8月にも追加登録あり |
たとえば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. 対応していない環境での挙動
フォント側は、OpenTypeのcmapテーブル(format 14)でIVSと字形の対応を実装します。4 対応フォント(IPAmj明朝など)と対応アプリが揃えば指定どおりの字形が出ます。
揃わない場合は、指定した字形が保たれるとは限りません。 次の2つを分けて考えます。
- 仕様上の正しい挙動: セレクタは無視され、基底文字の既定字形で表示される(セレクタ自体は見えない)
- 古いアプリや一部の描画系: セレクタが独立した未知の文字として扱われ、□が余分に表示される
つまりIVSは「劣化しても基底文字は読める」設計ですが、「指定した字形で必ず表示される」保証は受け手の環境次第です。
行政の住民記録・戸籍系では文字情報基盤系フォント+IVSという組み合わせが使われますが、一般の業務システムが安易に受け入れると、表示・印刷・連携先のどこかで字形が落ちます。
flowchart TB
accTitle: IVS付きデータの表示のされ方
accDescr: 対応フォントと対応アプリが揃えば指定どおりの字形で表示され、揃わなければセレクタが無視されて基底文字の既定字形になり、古いアプリや一部の描画系ではセレクタが未知の文字として□が余分に表示される
ivs["基底文字+異体字セレクタ"] --> env{"対応フォントとアプリが揃う?"}
env -->|はい| ok["指定どおりの字形で表示"]
env -->|いいえ| ignore["セレクタは無視され既定字形で表示"]
env -->|古いアプリや一部の描画系| tofu["□が余分に表示される"]
ignore -.-> spec["仕様上はこれが正しい挙動"]
図6: IVSは劣化しても基底文字は読めるが、指定字形で出るかは受け手の環境次第。
4.2. 実装上の注意 ── 「1文字」が最大4コード単位
IVSのセレクタU+E0100以降は追加面の符号位置なので、UTF-16では常にサロゲートペア(2コード単位)です。基底文字が追加面の漢字(たとえばJIS2004で追加された𠮟(U+20B9F))なら基底だけで2コード単位あり、利用者が「1文字」と認識する並びがUTF-16で最大4コード単位、UTF-8で最大8バイトになります。
文字数と切り出し: 見かけの1文字を分断しない
C#の"葛󠄀"(葛+VS17)はstring.Length == 3です。Substringや固定長での切り出しは、基底文字とセレクタを泣き別れにする危険があります。
文字数の検証・切り出しは、コード単位ではなく書記素単位(StringInfoなどのAPI)で行います。
保存: カラム長の単位を確認する
SQL Serverのnvarchar(n)はUTF-16コード単位です。DBのカラム長は、IVSを受け入れるなら見かけの文字数の2〜4倍を見込みます。
検索・比較: セレクタを区別するか決める
セレクタの有無で別の文字列になります。「葛」で検索して「葛+VS17」がヒットするかは、要件として決めて実装する必要があります。
flowchart TB
accTitle: IVS付きの1文字とUTF-16コード単位
accDescr: 利用者が1文字と認識する基底文字と異体字セレクタの並びは、セレクタが常にサロゲートペアで、基底文字が追加面の漢字ならさらに2コード単位あり、UTF-16で最大4コード単位になる
one["利用者が認識する1文字"] --> base["基底文字"]
one --> vs["異体字セレクタ"]
base -.-> bnote["追加面の漢字なら2コード単位"]
vs -.-> vnote["常にサロゲートペア(2コード単位)"]
base --> total["UTF-16で最大4コード単位"]
vs --> total
total -.-> risk["固定長の切り出しで泣き別れの危険"]
図7: IVS付きの1文字はUTF-16で最大4コード単位になり、コード単位での切り出しは危険。
5. 外字(EUDC) ── そのPCでしか出ない文字
外字は、Unicodeの私用領域(PUA: U+E000〜U+F8FF等)のコードポイントに、利用者が自分で字形を割り当てる仕組みです。私用領域のコードポイントには全世界共通の意味がなく、同じU+E000でもPCごと・組織ごとに別の字が割り当てられ得ます。5
字形は外字フォントに、データには番号が残る
Windowsでは外字エディタ(eudcedit.exe)で字形を作成し、eudc.tteというフォントファイルに保存されます。
このファイルは隠しフォントとしてインストールされ、HKEY_CURRENT_USER\EUDCのレジストリで各フォントに関連付けられます。6 Shift_JIS(CP932)時代は0xF040〜0xF9FCが外字領域で、Unicodeへ変換すると私用領域に対応付けられます。
データに番号があっても、相手が同じ字形を持っているとは限りません。 この仕組みから、次の問題が起きます。
- eudc.tteはそのPC(そのユーザー)のものであり、データと一緒に相手へ渡りません
- メール・PDF・Web・他システムに渡った瞬間、□になるか、相手側の別の外字に見えます
- OS移行やPC入れ替えでeudc.tteの移設を忘れると、「昔のPCでは出ていた字が出ない」が起きます
冒頭の2つ目の相談の正体はこれです。
flowchart TB
accTitle: 外字がそのPCでしか出ない理由
accDescr: 外字エディタで作成した字形はeudc.tteに保存されそのPCのレジストリでフォントに関連付けられるため、私用領域のコードだけがメールやPDFや他システムへ渡ると□になるか別の字に見える
edit["外字エディタで字形を作成"] --> tte["eudc.tteに保存"]
tte --> reg["レジストリでフォントに関連付け"]
reg --> local["そのPCでは表示できる"]
tte -.-> stay["eudc.tteはデータと一緒に渡らない"]
send["私用領域のコードだけが相手へ"] --> dest["メール・PDF・他システム"]
dest --> broken["□になるか別の字に見える"]
図8: 字形はeudc.tteに、データには私用領域の番号だけが残るため、外字はPCの外へ出ると壊れて見える。
5.1. 外字を受け取ってしまったシステムの現実解
問題は、レガシーシステムから引き継いだデータに外字が既に混ざっている場合です。当社が移行案件で推奨しているのは、調査 → 同定 → 置換 → 遮断の4段階です。
1. 調査: 使われている番号と元の字形を集める
データベース・ファイルを私用領域(U+E000〜U+F8FF)の正規表現でスキャンし、使用中の外字コードと件数を洗い出す。各拠点のPCからeudc.tteを回収して字形を確認する。
2. 同定: 代替文字対応表を作る
外字1つずつについて「正規のUnicode文字で表せるか」「IVSで表せるか」「文字情報基盤(MJ)に対応する文字があるか」を調べ、代替文字対応表を作る。単に旧字体をJIS外字で作っていただけ、というケースが実際には大半です。
3. 置換: 対応表に基づいてデータを置き換える
対応表に基づいてデータを置換する。どうしても対応する文字がない場合のみ、画像として保持するか、当該レコードに注記を持たせる。
4. 遮断: 新しい外字を増やさない
新システムでは私用領域の入力を検証で弾き、外字を新規に作らない。
flowchart TB
accTitle: 外字を含むデータの移行手順
accDescr: 私用領域のスキャンとeudc.tteの回収で使用中の外字を洗い出し、代替文字対応表を作って置換し、新システムでは私用領域の入力を検証で弾いて外字を新規に作らない
st1["調査:私用領域をスキャン"] --> st2["同定:代替文字対応表を作る"]
st2 --> st3["置換:対応表で置き換え"]
st3 --> st4["遮断:新規の外字を作らない"]
st1 -.-> tte["各拠点からeudc.tteを回収"]
st2 -.-> nomap["対応がない場合のみ画像か注記"]
図9: 外字の移行は調査・同定・置換・遮断の4段階で進め、新規の外字は作らない。
行政側でも方向性は同じで、自治体が独自に作ってきた外字(全国で約200万文字あるとも言われます)を、後述の行政事務標準文字へ一意に同定して使用をやめる方針が示されています。9 「外字を増やさず、標準化された文字集合へ同定する」は、官民問わず移行の定石になりつつあります。
6. 行政の文字基盤 ── 戸籍統一文字から行政事務標準文字へ
氏名を扱うシステムの設計では、行政側の文字基盤を知っておくと「どこまで受けるか」の判断材料になります。
まず、文字基盤の名前と役割を分ける
| 名称 | 管理 | 概要 |
|---|---|---|
| 戸籍統一文字 | 法務省 | 戸籍の電子化のために整理された約5万6千字。法務省のサイトで検索できる7 |
| 住基ネット統一文字 | 地方公共団体情報システム機構 | 住民基本台帳ネットワークで使う約2万1千字 |
| 文字情報基盤(MJ) | 文字情報技術促進協議会 | 行政事務で用いる約6万字を整備。MJ文字図形名で管理され、IPAmj明朝フォントとMJ文字情報一覧表が公開されている。IPAの事業として整備され、現在は同協議会へ移管8 |
| 行政事務標準文字(MJ+) | デジタル庁 | 文字情報基盤に、MJに同定できない戸籍の文字などを加えて拡張した文字セット。標準準拠システムの氏名等はこの文字セット、文字コードはJIS X 0221:2020を使う9 |
行政内の連携と、一般の外部環境との連携を分ける
自治体の基幹業務システム(標準準拠システム)では、氏名等の情報連携に行政事務標準文字を使い、スマートフォンなど統一的な連携規定がない外部システムとはJIS X 0213:2012の範囲で連携するという2段構えが標準仕様になっています。9
「内部では広い文字集合を保持し、外部とは一般的な環境で表示できる範囲でやり取りする」という、この構図自体が民間システムにも参考になります。
flowchart TB
accTitle: 標準準拠システムの2段構えの連携
accDescr: 自治体の標準準拠システムは氏名等の情報連携に行政事務標準文字を使い、統一的な連携規定がないスマートフォンなどの外部システムとはJIS X 0213:2012の範囲で連携する
sys["自治体の標準準拠システム"] --> renkei["氏名等の情報連携"]
sys --> gaibu["外部システムとの連携"]
renkei --> mjp["行政事務標準文字"]
gaibu --> jis["JIS X 0213:2012の範囲"]
gaibu -.-> sumaho["スマートフォンなど規定のない相手"]
mjp -.-> naibu["内部では広い文字集合を保持"]
図10: 行政連携は行政事務標準文字、規定のない外部連携はJIS X 0213:2012という2段構え。
自分のシステムで受け入れる範囲を決める
一般の業務システムへの実務指針としては、次をおすすめします。
- 受け入れ文字集合を決めて、仕様書と入力検証の両方で明示する。たとえば「JIS X 0213:2012の範囲」「私用領域と結合文字は不可」「IVSは受けない(または受けるが表示保証はIPAmj明朝環境のみ)」など
- 無制限に受けない。「Unicodeだから何でも入る」設計は、表示・印刷・連携のどこかで必ず破綻します
- 範囲外の文字への運用を決めておく。代替表記(新字体・カタカナ)への置き換えルール、本人へ説明する文言までがシステム仕様です
- 行政・金融など連携先に文字集合の規定がある場合は、それを正として合わせる
flowchart TB
accTitle: 受け入れ文字集合の設計と運用
accDescr: 受け入れる文字集合を決めて仕様書と入力検証の両方で明示し、範囲内の文字は受け入れ、範囲外の文字は代替表記への置き換えルールと本人へ説明する文言まで含めて運用を決めておく
decide["受け入れ文字集合を決める"] --> spec["仕様書で明示"]
decide --> valid["入力検証で明示"]
valid --> range{"範囲内?"}
range -->|はい| ok["受け入れる"]
range -->|いいえ| alt["代替表記へ置き換え"]
alt -.-> word["本人へ説明する文言も仕様"]
図11: 受け入れ文字集合は仕様書と入力検証の両方で明示し、範囲外の運用まで決めておく。
7. フォントの選定と埋め込み ── 画面と帳票を揃える
ここでは、使う環境にフォントがあるかを確認する → 画面と帳票で揃える → 許諾を確認してPDFに埋め込むという順に考えます。
7.1. 定番フォントの性格
| フォント | 収録 | 性格と使いどころ |
|---|---|---|
| MSゴシック / MS明朝 | Windows標準 | 低解像度画面向けに設計された古参。既定字形はJIS2004ベース2。レガシー帳票との互換性維持で今も現役 |
| メイリオ | Vista以降 | ClearType前提のモダンな画面向け書体。Vista世代のJIS2004移行と同時に登場1 |
| 游ゴシック / 游明朝 | Windows 8.1以降 | Windows/macOS双方に收録系列があり、資料の見た目を揃えやすい |
| BIZ UDゴシック / BIZ UD明朝 | Windows 10 1809以降 | モリサワ製のユニバーサルデザイン書体。帳票・画面の可読性重視の案件で第一候補14 |
| Noto Sans JP | 別途導入 | オープンソースで提供され、サーバーやLinux環境への同梱・Web配信がしやすい |
フォント名だけでなく、使う環境を確認する
選定で大事なのは書体の好みよりも、「表示・印刷・PDF生成に関わるすべての環境に、そのフォントが存在するか」です。
Windows 10/11の日本語補助フォント(BIZ UD等)は構成によっては入っていないことがあり、サーバーサイドでPDFを生成する構成ではサーバーのフォント有無が直接影響します。
flowchart TB
accTitle: フォント選定で確認すべき環境
accDescr: フォント選定では書体の好みよりも、表示と印刷とPDF生成に関わるすべての環境にそのフォントが存在するかが大事で、補助フォントの構成やサーバーのフォント有無が直接影響する
cand["候補フォント"] --> exist["すべての環境に存在するか"]
exist --> scr["表示する環境"]
exist --> prn["印刷する環境"]
exist --> srv["PDF生成サーバー"]
scr -.-> hojo["補助フォントは構成次第で無い"]
srv -.-> eikyo["サーバーのフォント有無が直接影響"]
図12: フォントは書体の好みより、表示・印刷・PDF生成のすべての環境にあるかで選ぶ。
7.2. 帳票設計の基本 ── 揃えて、埋め込む
画面と帳票のフォントを揃える
画面と帳票で同じフォントを指定する。 フォントが違えば同じデータでも字形が違って見え、冒頭のクレームになります。「画面はメイリオ、帳票はMS明朝」のような構成は、少なくともJIS2004の168字については字形差がないか確認しておくべきです。
PDFには、許諾を確認して埋め込む
PDFにはフォントを埋め込む。 埋め込まなければ、閲覧側は手元のフォントで代替描画し、字形どころかレイアウトも変わり得ます。
埋め込みの可否はライセンスで決まります。 OpenTypeフォントはfsTypeフィールドで埋め込み権限(Installable / Restricted / Preview & Print / Editable、サブセット禁止など)を宣言しており、埋め込みが許諾されていないフォントを埋め込んではいけません。10 商用フォントは契約の確認が必須です。
サブセット埋め込みを基本にする。 使用した文字のグリフだけを埋め込めば、日本語フォント全体(数MB〜数十MB)を抱え込まずに済みます。
長期保存にはPDF/Aを検討する
長期保存要件があるならPDF/A。 PDF/A(ISO 19005)は表示に必要な資源をファイル内で完結させる規格で、フォント埋め込みが必須です。11 「10年後に開いたら字形が変わっていた」を防ぐ最も確実な方法でもあります。
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出力の実装手段の選び方は「Windows業務アプリの印刷とPDF出力」で詳しく扱っています。
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属性やロケール)を正しく渡していないWebやアプリで起きやすい
- 豆腐(□)が出る: 指定フォントにもフォールバック先にもグリフがない。つまり□はフォールバックの「失敗の跡」であり、データは生きていることが多い
フォールバックは設計の代わりではない
フォールバックは救済装置であって、最初から正しいフォントを選ぶことの代替ではありません。15
業務アプリでは「主要な表示・印刷経路では設計したフォントだけで完結し、フォールバックは想定外文字の保険」と位置付けるのが健全です。多言語UIでのフォント選択の考え方は「WinForms/WPFアプリの多言語化」も参照してください。
9. 業務アプリの実装チェックリスト
最後に、入力から連携までの各層で確認すべきポイントを表にまとめます。画面で表示できたかだけで終わらせず、保存・印刷・連携までを確認してください。
| 層 | 典型的な事故 | 設計・実装の要点 |
|---|---|---|
| 入力 | IMEから環境依存文字・IVS付き文字・私用領域の文字が入る | 受け入れ文字集合を決めて検証する。範囲外はエラーではなく案内(代替表記の提示)にすると窓口業務が回る |
| 正規化 | NFKCで「㈱」→「(株)」、全角半角の統合、①→1など意図しない変換。NFCでもCJK互換漢字(例: U+FA19の「神」)が統合漢字U+795Eに置き換わる | 氏名・住所にNFKCをかけない。正規化は用途(検索キー生成など)を限定し、原本は入力どおり保存する12 |
| 保存 | サロゲートペア・IVSでカラム長不足、コード単位での切り詰め | UTF-8/UTF-16で保存し、カラム長はコード単位で余裕を持たせる。切り出しは書記素単位で行う |
| 表示 | フォントにグリフがなく□、フォールバックで字形が変わる | 対象文字集合を表示できるフォントを明示指定し、対象OSの標準収録状況を確認する |
| 印刷・PDF | 画面と帳票の字形差、閲覧側での代替描画 | 画面と帳票のフォントを揃え、PDFにはライセンスを確認のうえサブセット埋め込みする10 |
| 他システム連携 | Shift_JIS(CP932)変換でJIS X 0213の追加漢字・IVS・外字が?や〓に化ける |
連携仕様で文字コードと文字集合を明示する。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はVista以降JIS2004字形が既定です。「葛」「辻」「飴」の形が環境で違うのは、データ破損ではなくフォントの歴史です。
設計: 字形の指定と受け入れ範囲を決める
- 字形をデータで固定する標準手段はIVSですが、対応フォント・対応アプリが揃わなければ既定字形に落ちます。1文字が最大4 UTF-16コード単位になる実装上の影響も忘れないでください。
- 外字(EUDC)はそのPC固有の資産で、データと一緒には旅ができません。移行時に洗い出し、正規の文字やIVSへの対応表で置き換え、新規作成はやめるのが現実解です。
- 氏名を扱うシステムは受け入れ文字集合を決めて明示します。行政は戸籍統一文字・文字情報基盤を土台に行政事務標準文字へ標準化を進めており、連携するシステムはその動向を追う必要があります。
実装・出力: 原本を守り、表示経路を揃える
- 帳票・PDFは「画面とフォントを揃えて、ライセンスを確認して埋め込む」が基本です。長期保存にはPDF/Aを検討してください。
- NFKC正規化・コード単位の切り出し・CP932変換は、異体字と外字を静かに壊す三大ポイントです。原本保存と書記素単位の処理を原則にしてください。
次に「字が違う」と言われたら、最初にこう問い直してください。コードポイントは同じか、違うのか。同じならフォントの問題、違うならデータの問題です。この一手で、調査の入口を間違えなくなります。
flowchart TB
accTitle: 調査の入口を決める最初の問い
accDescr: 字が違うと言われたら最初にコードポイントが同じか違うかを比較し、同じならフォントの問題、違うならデータの問題として調査を始める
said["字が違うと言われた"] --> cmp{"コードポイントは同じ?"}
cmp -->|同じ| fontp["フォントの問題"]
cmp -->|違う| datap["データの問題"]
図16: コードポイントが同じならフォント、違うならデータの問題として調査を始める。
関連記事
- Windows文字コード入門 - Linux連携で起きる文字化け
- Windowsの文字コードと改行コード - 文字化けとCRLF/LFの基本
- Windows業務アプリの印刷とPDF出力 ── System.Drawing.Printing / WPF / 帳票ライブラリの使い分け
- WinForms/WPFアプリの多言語化 ── resx・サテライトアセンブリ・カルチャ切り替えの実務
- CSVは「ただのテキスト」ではない ── C#業務アプリのCSV実務(文字コード・Excel互換・インジェクション対策)
- Windowsアプリのアクセシビリティ入門 ── UI Automationと合理的配慮の義務化に備える
関連する相談領域
合同会社小村ソフトでは、業務システムの文字まわりの設計・調査を扱っています。「画面と帳票で字が違う」「移行したら氏名が□になった」といった症状の原因切り分け、レガシーシステムからの移行時の外字調査と代替文字表の作成、氏名を扱うシステムの受け入れ文字集合の設計、帳票・PDFのフォント埋め込み構成のレビューまで、コード層とフォント層の両方から対応します。
参考リンク
-
株式会社モリサワ, JIS X 0213:2004(JIS2004)|フォント用語集. 表外漢字字体表を受けてJIS X 0213:2004で168字の漢字の例示字形が印刷標準字体(いわゆる康熙字典体)に改められたこと、Windows VistaにJIS2004対応フォントが標準搭載されたことについて。 ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, MS Gothic font family. MSゴシックファミリーの既定字形がJIS2004ベースであり、OpenTypeの’jp90’フィーチャ経由でJIS90のレガシー字形にアクセスできることについて。 ↩ ↩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
-
Microsoft Learn, cmap — Character to Glyph Index Mapping Table (OpenType spec). OpenTypeフォントがcmapサブテーブルformat 14でUnicode Variation Sequenceを実装すること、default/non-default UVSの区別、JIS2004対応フォントでの利用例について。 ↩ ↩2
-
Microsoft Learn, End-User-Defined and Private Use Area Characters. 外字(EUDC)と私用領域(PUA)文字が利用者や団体ごとに独自に定義され、同じコードポイントでもコンピューターによって割り当てが異なり衝突し得ることについて。 ↩ ↩2
-
Microsoft Learn, Character Sets and Fonts. UnicodeのEUDC用途にはPUA(U+E000〜U+F8FF等)が使われること、外字エディタでグリフを作成すること、EUDCフォントが.tteファイルとして隠しインストールされ、HKEY_CURRENT_USER\EUDCレジストリでフォントに関連付けられることについて。 ↩ ↩2
-
法務省, 戸籍統一文字情報 検索条件入力. 法務省が提供する戸籍統一文字の公式検索サイト。戸籍で用いられる文字の字形・読み・関連情報を検索できることについて。 ↩ ↩2
-
一般社団法人文字情報技術促進協議会, 文字情報基盤整備事業. IPAが経済産業省等の支援のもと整備した、行政事務で用いる約6万字の漢字を対象とする文字情報基盤(MJ文字図形、MJ文字情報一覧表、IPAmj明朝フォント)が、現在は同協議会に移管されて公開されていることについて。 ↩ ↩2
-
デジタル庁, 地方公共団体情報システムにおける文字要件の運用に関する検討会報告書(令和6年7月). 自治体で使用される外字が約200万文字あるとも言われること、文字情報基盤を拡張した「行政事務標準文字」(通称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、サブセット禁止ビット等)を定義し、埋め込みが許諾されていないフォントをアプリケーションが埋め込んではならないことについて。 ↩ ↩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の4形式、KC/KD形式が全角半角文字などの互換文字を統合して情報が失われるため文字列の正規保存形式として一般に適さないことについて。 ↩ ↩2
-
Unicode Consortium, Ideographic Variation Database. UTS #37に基づくIVSの登録簿。Adobe-Japan1(2007年)、Hanyo-Denshi(2010年)、Moji_Joho(2014年)などのコレクションが登録され、2026年8月版でもMoji_Johoコレクションへの追加登録が行われていることについて。 ↩
-
Microsoft Learn, BIZ UDGothic font family. モリサワ製のユニバーサルデザイン書体BIZ UDゴシックがWindows 10 バージョン1809以降の日本語補助フォントとして収録されていることについて。 ↩
-
Microsoft Learn, Fonts (Globalization documentation). フォントフォールバックの仕組み、GDIのフォントリンク(FontLink\SystemLinkレジストリ)、既定グリフ(トーフ)の意味、フォントリンクが正しいフォント選択の代替ではないことについて。 ↩ ↩2
関連する記事
同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。
Windowsの文字コードと改行コード - 文字化けとCRLF/LFの基本
Windows で混ざりやすい Shift_JIS / UTF-8 / UTF-16、文字化け、CRLF / LF の違いを、実務で判断しやすい形に整理します。
Windowsアプリのダークモードとコントラストテーマ対応 ── DWMのダークタイトルバー、WinForms/WPFのシステムテーマ追従、ハイコントラスト時の描画
Windows 11のダークモードとコントラストテーマにWinForms/WPFアプリを追従させる方法を解説。DWMのダークタイトルバー、.NET 9/10のSetColorModeとThemeMode、テーマ切替の検知、ハイコントラスト時のシステムカラー描画を整理します。
Windowsのプリンタードライバー終了 ── 業務アプリの帳票・ラベル印刷はどう備えるか
Microsoftはv3/v4プリンタードライバーの提供終了を段階的に進めており、2026年7月からはIPPクラスドライバーが優先されます。Windows protected print modeで何が消えるか、業務アプリの帳票・ラベル印刷の依存箇所の棚卸しと備え方を判断表...
スリープ復帰で壊れるアプリ ── 電源イベントの仕組みと復帰に強い業務アプリの作り方
ノートPCを開いたら業務アプリの通信が切れていた――原因はスリープを想定しない設計です。WM_POWERBROADCASTによる通知の流れ、Modern Standbyの挙動、切断・再接続の設計、スリープ抑止と調査コマンドまでを一次情報で解説します。
Windowsアプリのアクセシビリティ入門 ── UI Automationと合理的配慮の義務化に備える
2024年4月施行の改正障害者差別解消法を背景に、スクリーンリーダーがWindowsアプリを読む仕組みUI Automationを軸として、WinForms/WPFでの名前付け、キーボード操作、コントラスト、検証ツールまで実務目線で整理します。
関連トピック
このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。
Windows技術トピック
Windows 開発、不具合調査、既存資産活用の技術トピックをまとめた入口です。
このテーマがつながるサービス
この記事は次のサービスページにつながります。近い入口からご覧ください。
Windowsアプリ開発
業務アプリ、装置連携、通信ツールなどの Windows ソフト開発を支援します。
よくある質問
この記事のテーマについて、相談時によくある質問をまとめています。
- 同じ「葛」の字なのに、PCや帳票によって形が違って見えるのはなぜですか?
- 文字化けではなく、フォントの字形の違いである可能性が高いです。JIS X 0213:2004(JIS2004)で168字の漢字の例示字形が印刷標準字体に改められ、WindowsもVista以降のMSゴシック/MS明朝などがJIS2004字形を既定にしました。「葛」「辻」「飴」などはこの代表例で、Unicodeの符号位置(データ)は同じまま、フォントが持つグリフ(見た目)だけが変わっています。したがってデータを比較すれば一致しており、XP時代の帳票イメージと新しいPCの画面で形が食い違うのは仕様どおりの動作です。字形まで揃えたい場合は、画面と帳票で同じフォントを使うか、異体字セレクタで字形を指定します。
- 異体字セレクタ(IVS)を使えば、人名の字形の問題はすべて解決しますか?
- 解決しません。IVSは基底文字の直後にU+E0100以降のセレクタを付けて字形をデータとして指定する仕組みで、IPAmj明朝などの対応フォントと対応アプリが揃って初めて指定どおりに表示されます。非対応の環境ではセレクタが無視されて基底文字の既定字形で表示されるのが正しい挙動で、環境によってはセレクタが□に見えることもあります。さらに、IVS付きの1文字はUTF-16で最大4コード単位になるため、文字数カウント・切り出し・DBのカラム長の設計にも影響します。導入する場合は、表示・印刷・連携先まで含めて対応範囲を確認したうえで使ってください。
- 外字(EUDC)で登録した文字は、他のPCやPDFでも表示できますか?
- 原則として表示できません。外字はUnicodeの私用領域(U+E000〜)に、そのPCのeudc.tteファイルへ利用者が字形を登録する仕組みで、同じコードポイントでも別のPCでは未定義か別の字形になります。そのため、メール・PDF・他システムへ渡ると□になったり違う字に見えたりするのが宿命です。既に外字を含むデータを預かっている場合は、移行時に私用領域の使用箇所を洗い出し、正規のUnicode文字や異体字セレクタへの対応表を作って置き換えるのが現実的です。新規システムで外字を新しく作ることは避けるべきです。
- 業務システムで氏名の文字はどこまで受け入れるべきですか?
- 「受け入れる文字集合を決めて、仕様として明示する」ことが第一です。戸籍には約5万6千字の戸籍統一文字があり、行政の標準準拠システムは文字情報基盤を拡張した行政事務標準文字を使う方針ですが、一般の業務システムが同じ水準を無制限に受け入れる義務はありません。たとえば「JIS X 0213の範囲まで」「異体字セレクタと私用領域は受け付けない」のように範囲を決め、入力時に検証して範囲外はアラートや代替表記で運用する設計が現実的です。行政システムや自治体と連携するシステムだけは、行政事務標準文字とJIS X 0221ベースの連携要件の動向を追う必要があります。
- 帳票やPDFで画面と同じ字が出るようにするにはどうすればよいですか?
- まず画面と帳票で同じフォントを指定し、PDFにはフォントを埋め込むのが基本です。フォントが違えば同じデータでも字形が変わり得ますし、閲覧側のPCにフォントがなければ代替フォントで描画されて見た目が崩れます。埋め込みの可否はフォントのライセンス(OpenTypeのfsType)で決まっているため、帳票ライブラリ任せにせず確認してください。使用した文字だけを埋め込むサブセット埋め込みならファイルサイズも抑えられます。長期保存が要件ならフォント埋め込みが必須のPDF/Aを検討します。