偵測所有必需的字形是否可用

偵測所有必需的字形是否可用

在 XeTeX 中,如果目前字型沒有可用的字形,則會在日誌檔案中列印一則訊息。輸入

\documentclass{scrartcl}

\begin{document}
  α
\end{document}

導致日誌中出現以下條目:

Missing character: There is no α in font cmr10!

有沒有一種方法可以檢查給定的輸入是否存在渲染所需的所有字形都可用,而不依賴日誌檔案?顯然,沒有刷新日誌檔的命令,並且(在我通過管道進入正在運行的 XeLaTeX 進程的情況下)我想在 XeTeX 終止之前知道。

答案1

更長的帖子

許多年前,這個任務對我來說是一個大問題,當時我正在排版和生成字體預覽書,我需要在實際排版之前了解有關字形的所有類型資訊。我將答案分為三個小部分,每個部分都有可編譯的 TeX 檔案。


第 1 部分:xelatex及其工具

有一種方法xelatex,在第8頁間接提到參考手冊。我們可以使用該\XeTeXcharglyph命令並檢查輸出是否0(或.notdef是否檢查字形名稱)。一旦未定義任何字形,零值就會指派給字元槽。

在這一步驟之後,我們可以使用\ifnum...\else...\fi語句來決定要排版的內容(如果有的話)。在範例中,我正在測試四個字母,? A \ a其中兩個已定義,其餘兩個未定義。我已經從 Manfred Klein 的收藏中下載並安裝了 RodgauApesInitials,http://moorstation.org/typoasis/designers/klein04/deco/rodgau_apes.htm

我們運行xelatex mal-kanji1.tex並終端顯示:

The glyph slot of 003F(hex) is: 0 (.notdef)
The glyph slot of 0041(hex) is: 3 (A)
The glyph slot of 005C(hex) is: 0 (.notdef)
The glyph slot of 0061(hex) is: 29 (a)

這是代碼:

% run: xelatex mal-kanji1.tex
\documentclass[a4paper]{article}
\pagestyle{empty}
\usepackage{xltxtra}
\usepackage{fontspec}
\usepackage{pgffor}
\begin{document}
%\font\malfont=RodGauApes.ttf
\font\klein="RodGauApes Initials"
\font\cmr=cmr10%
\message{^^J}% One \n to the terminal...
% U+0041, A, dec 65
\def\checkme#1{%
\klein\message{The glyph slot of #1(hex) is: \the\XeTeXcharglyph"#1 \space 
  (\XeTeXglyphname\klein\XeTeXcharglyph"#1)^^J}%
%! Cannot use \XeTeXcharglyph with cmr10; not a native platform font.
\ifnum\XeTeXcharglyph"#1=0%
\cmr Undefined glyph!%
  \else 
\klein\char"#1%
\fi% End of \ifnum...
}% End of \checkme...
\foreach \malglyph in {003F,0041,005C,0061}% ? A \ a
  {\checkme\malglyph\cmr\par%
  }% End of \foreach...
\end{document}

MWE,第 1 部分

當我排版漢字預習本時,我需要並且使用了這個策略。我使用了許多不同的字體,我需要確切地知道要排版多少個字形。如果缺少一個或多個字形,則由我決定是否要排版該矩形。應該說,字體缺少一些CJKV字元是很正常的,因為這樣的字元實在太多了。我附上書中的快照,它是單一日文/漢字的預覽。

漢字書:快照

最大的缺點是我們只能對格式使用此策略xelatex,並且只能檢查較新的字體(TTF、OTF),它不適用於 PFB。這是工作上的嚴重限制。讓我向您展示其他方法。


第2部分:testfont.tex

TeX 發行版中的工具之一是testfont.texfile。如果我們運行,例如:

pdftex testfont.tex

系統會詢問我們字體的名稱,讓我們使用dmjhira並按 Enter 鍵。當我們使用\help並按 Enter 鍵時,會出現一個選項清單。常見的選項是寫入\table\bye後按 Enter。我們正在獲取該testfont.pdf文件,這是它的預覽。

MWE,第 2 部分

問題是我們無法自訂它,並且在不安裝和設定字體的情況下無法輸入 TTF 和 OTF 字體。值得檢查另一種方法。

第 3 部分:測量 TeX 框(平假名和片假名作為測試案例)

TeX 的核心是測量盒。這是我們將要使用和測試的方法。我們將測試單個字形,但我們可以輕鬆測量幾乎任何東西。定義一個新框 ( \newbox) 後,我們虛擬地實作了該框 ( \setbox),並且可以測量該框的寬度、高度和深度 ( \wd\ht\dp)。

在下面的範例中,我們排版了日文五十音表平假名,但我們可能會發現一些缺陷。有一個開放的空間,線條不理想,空間在收縮和拉伸,我們不知道排版了多少字形。但這是進一步探索的起點。

值得一提的是,我們可以運行任何主要latex引擎,如果我們使用例如fontspec包中,我們可以在運行時測試 TTF、OTF 和一些 dfont 檔案中的字形lualatexxelatex.我附上 TeX 程式碼和結果預覽。

% run: *latex mal-kanji2.tex
\documentclass[a4paper]{article}
\pagestyle{empty}% No page number please...
\parindent=0pt% No indentation please...
\rightskip=6cm% And TeXie, :-), please narrow the text width somehow...
\begin{document}
\font\hira=dmjhira at 2ex% Setting up a new font face (Hiragana)...
\newcount\malcounter% Setting up a new counter...
\malcounter=-1% The initialization of the counter
\loop% The core of this example...
  \advance\malcounter by 1% Move on to the next glyph...
  {\hira\char\malcounter} % Show me the glyph, add space...
  %\discretionary{}{}{}% Allow a page break after the glyph... (the first alternative)
   \allowbreak% (the second alternative)
\ifnum\malcounter<255\repeat% Run all 256 characters in the font...
\end{document}

MWE,第 3a 部分


只有當字形寬度為非零值時,我們才會排版字形。裝飾字體也有一些例外,但它被認為是不好的字體。我們添加一個計數器 ( \newcount) 來處理許多排版字形,我們將空間限制為固定尺寸(\fontdimen3、4 和 7),我們允許換行,簡單地說我們現在可以完全控制輸出。

我附上一個範例和帶有片假名(日語音圖)的 PDF 檔案的預覽。

% run: *latex mal-kanji3.tex
\documentclass[a4paper]{article}
\pagestyle{empty}
\parindent=0pt
\begin{document}
\newbox\emptybox
\setbox\emptybox=\hbox{}
\newbox\malbox
\font\kata=dmjkata% A new font face to be used (Katakana)...
\newcount\counter 
\counter=-1% The counter of glyphs...
\fontdimen3\font=0pt \fontdimen4\font=0pt \fontdimen7\font=0pt 
% Eliminate the stretch in spaces, or, we could use \makebox...
\loop% Process all the glyphs...
  \advance\counter by 1% Go to the next glyph...
  \setbox\malbox=\hbox{\kata\char\counter}% Measure the glyph...
  \ifnum\wd\malbox=\wd\emptybox\relax\else% Is width 0pt? Height is not tested (\ht, \dp)...
    \texttt{\ifnum\counter<10 0\fi% Add zero in front of number <10...
    \the\counter.\copy\malbox\ }% Show me the glyph...
    \discretionary{}{}{}%Allow the line break, or, \allowbreak...
  \fi% End of \ifnum condition...
\ifnum\counter<255\repeat% Show me all the glyphs in range 0-255...
\end{document}

MWE,第 3b 部分


結論

這些方法有一些限制。我們無法測試兩個字形是否不只是旋轉、翻轉或縮放,我們也不會列出 0-255 區域之外的字形。如果您需要類似的東西,請使用字體鍛造,它可以在那裡完成,因為它有自己的腳本語言和支持Python腳本

如果您想知道這封信下最後一個字母的第一個示例中的飛濺是什麼:哦,是的,那是偉大的曼弗雷德·克萊因傳奇字體創造者本人的一隻猿!我附上來自的螢幕截圖字體鍛造以及他的字體預覽,其中包含 26+26 個字母。

曼弗雷德·克萊因,第 1 部分

曼弗雷德·克萊因,第二部

答案2

作為 Malipivo 優秀答案的擴展,我想提一下,您也可以使用\iffontchar以下範例所示的內容。請注意,LuaLaTeX 給出的結果與 XeLaTeX 的結果不同——看起來 XeLaTeX 不喜歡 Unicode 最高範圍內的字形(可能高於 U+F0000)。

程式碼應該相當明顯,但想法是你調用

\fontrange {xits-math.otf} {1} {"FFFFF} { \texttt{\small #2}:\quad #3\par}

其中第一個參數是 fontspec 字體,第二個是起始字形點,第二個是結束字形點,第四個參數定義結果的排版方式(#2是字形的十六進位代碼,#3是與字形本身) 。

\documentclass[a4paper]{article}
\usepackage{fontspec,multicol}
\usepackage[margin=2cm]{geometry}
\begin{document}

\ExplSyntaxOn
\DeclareDocumentCommand \fontrange { m m m +m }
 {
  \group_begin:
  \cs_set:Npn \__typeset:nnn ##1 ##2 ##3 {#4}
  \fontspec{#1}
  \int_step_inline:nnnn {#2} {1} {#3}
   {
    \iffontchar\font ##1\relax
      \__typeset:nnn {##1} { \int_to_Hex:n {##1} } { \char ##1 \relax }
    \fi
   }
  \group_end:
 }
\ExplSyntaxOff

\begin{multicols}{5}
\fontrange{xits-math.otf}{1}{"FFFFF}
  { \texttt{\small U+#2}:\quad #3\par}
  % #1 = glyph slot, decimal
  % #2 = glyph slot, hex
  % #3 = char
\end{multicols}

\end{document}

相關內容