マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

フォントにない文字を別のフォントで補う

2011-01-26 の記事のコメントについて:


たとえば,日本語の中にほんのすこし中国語が混在するような場合とか,手持ちのフォントがadobe1-4しかカバーしていない時,自動で補完すること(unicode によるフォント割付)はできないかとおもっています。

「メインの」フォントにグリフがない文字について、別の「サブの」フォントで代替するという処理自体は、XeTeX の「文字間トークン自動挿入」の機能を用いれば、原理的には可能である。


\documentclass[a4paper]{article}
\usepackage{fontspec}
\setmainfont[RawFeature=-palt]{IPAexゴシック} % 「メイン」フォント
\newfontfamily\altfamily{花園明朝} % 「サブ」フォント
\makeatletter %!!!!!!!!!!!!!!!!!!!!!!!!!
\newcount\xx@uc
\newcount\xx@maxuc
%% \rmfamily のフォントに存在する、文字クラス 1 の
% 文字を全て文字クラス 4 に移動
\def\xx@migrate#1#2{%
\xx@uc=#1\xx@maxuc=#2\relax \loop
\ifnum\XeTeXcharclass\xx@uc=1 \iffontchar\font\xx@uc
\XeTeXcharclass\xx@uc=4
\fi\fi
\ifnum\xx@uc<\xx@maxuc \advance\xx@uc 1 \repeat}
\rmfamily
\xx@migrate{0}{"FFFF}\xx@migrate{"20000}{"2FFFF}
%% 文字間挿入トークン列(\XeTeXinterchartoks)の設定
% * (N,1) → (N,4)、(1,N) → (4,N) にコピー
% * (N,1) の末尾に \bgroup\altfamily を追加
% * (1,N) の先頭に \egroup を追加
\def\xx@copy@ictoks#1#2#3#4{%
\XeTeXinterchartoks #1 #2=\expandafter{\the\XeTeXinterchartoks #3 #4}}
\def\xx@appto@ictoks#1#2#3{%
\XeTeXinterchartoks #1 #2=\expandafter{\the\XeTeXinterchartoks #1 #2 #3}}
\def\xx@preto@ictoks#1#2#3{% #3は単一トークンに限る(手抜き)
\XeTeXinterchartoks #1 #2=\expandafter{\expandafter#3%
\the\XeTeXinterchartoks #1 #2}}
\@for\xx@x:=0,1,2,3\do{%
\xx@copy@ictoks{\xx@x}{4}{\xx@x}{1}\xx@copy@ictoks{4}{\xx@x}{1}{\xx@x}}
\xx@copy@ictoks{4}{4}{1}{1}
\@for\xx@x:=0,1,2,3,4,255\do{\xx@appto@ictoks{\xx@x}{1}{\bgroup\altfamily}%
\xx@preto@ictoks{1}{\xx@x}{\egroup}}
% 文字間トークン自動挿入を有効にする
\XeTeXinterchartokenstate=1
\makeatother %!!!!!!!!!!!!!!!!!!!!!!!!!
\begin{document}

% IPAexゴシックにない(簡体中文の)文字を含むテキスト
我的气垫船充满了鳝鱼!

\end{document}

この例は文書のメインのフォントを「IPAexゴシック」(判別を容易にするため敢えてゴシックにしている)にするが、そこで足りない文字は「花園明朝」で出力するというものである。結果は以下のようになる。

ただこれを実用にしようとする時に大きな問題がある。

(続きは「文字間トークン自動挿入機能の話で)