Closed GreenYun closed 4 years ago
您的問題非常不明確。
在您沒有提供可編譯的「最小工作示例」時,我們無法復現您所述的問題。而且基於以上分析,幾乎可以斷定問題與 CTeX 宏集無關,所以決定 close 本條 issue。如果可以提供「最小工作示例」,會考慮重新 open 的。
您的問題非常不明確。
- Hinting 是字體內部的數據,如果是字體本身有問題,那麼就跟 CTeX 無關。
- 主流的 TeX 引擎全部都不支持「合成中文字」,字體有的字符才輸出得了,您確定「合成」的字是用 LaTeX 編譯輸出的嗎?
- 「中文文本字高不一」不僅跟字體內部的 hinting 有關,還跟 PDF 瀏覽器有關。
在您沒有提供可編譯的「最小工作示例」時,我們無法復現您所述的問題。而且基於以上分析,幾乎可以斷定問題與 CTeX 宏集無關,所以決定 close 本條 issue。如果可以提供「最小工作示例」,會考慮重新 open 的。
我認爲問題非常明確,顯然是與 TeX 或其宏集有關。我不敢認爲 XeLaTeX 或者 fontspec 曾或有需要考慮相關問題,畢竟其原來爲英文排版引擎;而對於中文而言,有必要限定每個字是處於等大的方框當中。的確,字體的這種「不等高」與字體本身hinting息息相關,但是,如同 Adobe InDesign,這問題應當交由漢字書寫器解決,這時我認爲 CJK 等宏集有必要考慮相關問題。
細明體是華康公司的字體,其設計方案是利用 hinting 像中文字的筆畫拼湊連結;而由於其筆畫乃是造於 Unicode private 區域的方塊字,直接引用該字引致完整字符邊界大於文字邊界。而通常而言,這個問題可以通過讀取字體相關 width 或 height 數據修正,以忽略這些空白區域。但是LaTeX渲染時並沒有限定字體高度邊界,於是導致行高不一的問題。同時,若改爲豎排中文文本,並不會發生因爲 glyph 越界而引起的不對齊現象,證明此問題當可以有辦法修正。
以下可以給出一個示例,使用思源 (Noto) 宋體作爲參考字體。思源字體有輕微該問題,示例上不算非常明顯。但是提出本 issue 是希望修正各字體用於排版時所遇到的問題。因不方便上載細明體等相關商業字體,附圖一張而鑑證該問題。
\documentclass{article}
\usepackage{xltxtra}
\usepackage{xeCJK}
\setCJKmainfont{Noto Serif CJK TC}
\begin{document}
觀自在菩薩,行深般若波羅蜜多時,照見五蘊皆空,度一切苦厄。舍利子,色不異空,空不異色;色即是空,空即是色。受、想、行、識,亦復如是。舍利子,是諸法空相,不生不滅,不垢不淨,不增不減,是故空中無色,無受、想、行、識;無眼、耳、鼻、舌、身、意;無色、聲、香、味、觸、法;無眼界,乃至無意識界;無無明,亦無無明盡;乃至無老死,亦無老死盡。無苦、集、滅、道,無智亦無得。以無所得故,菩提薩埵,依般若波羅蜜多故,心無罣礙,無罣礙故,無有恐怖,遠離顛倒夢想,究竟涅槃。三世諸佛,依般若波羅蜜多故,得阿耨多羅三藐三菩提。故知般若波羅蜜多,是大神咒,是大明咒,是無上咒,是無等等咒,能除一切苦,真實不虛。故說般若波羅蜜多咒,即說咒曰:揭諦揭諦,波羅揭諦,波羅僧揭諦,菩提薩婆訶。
\end{document}
以下是另一個代碼,意圖爲每個字構造一個實際渲染邊框。通常,LaTeX 對所有文字均使用這種邊框作爲文字邊界渲染,同時由於 \baselineskip
等參數確定行高。然而由於字符邊界溢出關係,超越了 \baselineskip
,導致行距不一。
\documentclass{article}
\usepackage{xltxtra}
\usepackage{xeCJK}
\setCJKmainfont{新細明體}
\makeatletter
\def\showboxes#1{%
\begingroup\fboxrule=.1pt\fboxsep=-\fboxrule
\@showboxes#1\@showboxes\@empty
\endgroup}
\def\@showboxes#1#2{%
\ifx#2\@showboxes
\fbox{#1}\expandafter\@gobble
\else
\setbox0=\hbox{#1\kern0pt#2}\setbox2=\hbox{#1#2}%
\dimen0=\wd0 \advance\dimen0 -\wd2
\fbox{#1}\kern-\dimen0
\expandafter\@showboxes
\fi#2}
\makeatother
\begin{document}
\showboxes{觀自在菩薩,行深般若波羅蜜多時,照見五蘊皆空,度一切苦厄。舍利子,}\\
\showboxes{色不異空,空不異色;色即是空,空即是色。受、想、行、識,亦復如是。舍}\\
\showboxes{利子,是諸法空相,不生不滅,不垢不淨,不增不減,是故空中無色,無受、}\\
\showboxes{想、行、識;無眼、耳、鼻、舌、身、意;無色、聲、香、味、觸、法;無眼}\\
\showboxes{界,乃至無意識界;無無明,亦無無明盡;乃至無老死,亦無老死盡。無苦、}\\
\showboxes{集、滅、道,無智亦無得,以無所得故。菩提薩埵,依般若波羅蜜多故,心無}\\
\showboxes{罣礙,無罣礙故,無有恐怖,遠離顛倒夢想,究竟涅槃。三世諸佛,依般若波}\\
\showboxes{羅蜜多故,得阿耨多羅三藐三菩提。故知般若波羅蜜多,是大神咒,是大明}\\
\showboxes{咒,是無上咒,是無等等咒,能除一切苦,真實不虛。故說般若波羅蜜多咒,}\\
\showboxes{即說咒曰:揭諦揭諦,波羅揭諦,波羅僧揭諦,菩提薩婆訶。}
\end{document}
邊框渲染效果如圖
思源字體的邊界溢出量很少,並不過於 \baselineskip
因此不造成排版影響。
所以試圖減少 \baselineskip
及 \baselinestretch
,這時問題產生。比較明顯的是單倍行距下,(舉一個極端的例子)把某一行文字變成「一一一一一一一」,這時能看出間距疏密不一來。
@GreenYun 首先要感謝您提供可以編譯運行的 MWE。因為現在有了更詳細的信息,我可以解答您觀察到的問題了。
您看到的「『字框』高低不均勻」,既不是字體 hinting 的問題、又不是 CTeX 宏集的問題。
\showboxes
畫出來的並不是真正的「字框」。的確,每一個漢字在 TeX 眼裡只不過是一個又一個的「盒子」。當您使用 TrueType、OpenType 字體時,每個盒子的「寬度」的確是對應到該字符 bounding box 的寬度。但是盒子的高度並不是對應到「字框的高度」,盒子的深度也並不是對應到「字框的深度」。高度與深度對應到的是該字符「字形」本身的高度與深度(但是不允許正常的高度、深度小於零)。
以思源宋體為例,\showboxes
畫出來漢字「一」、居中標點「,」「。」的框,寬度的確是全角字號大小,但是深度皆為零,高度則是字形頂端。
事實上,中文字型設計「要求字形在字框裡佔據不一樣的物理位置」,需要實現的是「看起來字形像在字框裡的同樣位置」,視覺位置不等於物理位置。
最典型的例子是「上」、「下」兩字。它們的字形外觀是三角形,位置是需要視覺微調的。「上」字會偏上,而「下」字會偏下,造成一種重心、中線平穩的視覺感受。
如上所述,思源宋體其實不存在字框高低不均勻的問題,因為它的漢字字框「頂線」統一設定在「880」,而「底線」統一設定在「120」。每個漢字字形本身都在字框內部。由此也可以看出,西文小寫字母「p」、「q」的降部一定是會撐破漢字字框底線的。
新細明體渲染出來的第一行「菩」「多」「時」「照」「皆」「厄」「舍」這些字都是有問題的,因為畫出來框框的底部並沒有跟字形相切。
@GreenYun 如下示例修改自您提供的示例,我並不能復現您的問題:
\documentclass{article}
\usepackage{xeCJK}
\setCJKmainfont{新細明體}
\makeatletter
\def\showboxes#1{%
\begingroup\fboxrule=.1pt\fboxsep=-\fboxrule
\@showboxes#1\@showboxes\@empty
\endgroup}
\def\@showboxes#1#2{%
\ifx#2\@showboxes
\fbox{#1}\expandafter\@gobble
\else
\setbox0=\hbox{#1\kern0pt#2}\setbox2=\hbox{#1#2}%
\dimen0=\wd0 \advance\dimen0 -\wd2
\fbox{#1}\kern-\dimen0
\expandafter\@showboxes
\fi#2}
\makeatother
\begin{document}
\Huge
\showboxes{EOL}\\
\showboxes{觀自在菩薩,}
\end{document}
西文大寫字母「E」「O」「L」本該在西文基線對齊,是不是發現「O」的底部(還有頂部)也要稍微突出一點?這種西文的視覺微調叫「overshoot」,目的是為了「平的筆畫」和「圓的筆畫」看起來是對齊的。視覺微調在中文西文裡面都存在,但是我測試的結果卻是新細明體沒有明顯地「不平」。
我的「新細明體」中的「菩」字底部,並沒有出現很多空白哦。而且我注意到了您提供的截圖裡面,「菩」字的「艹」部件是連起來的橫筆,然而我截圖裡面的「艹」部件是斷開的橫筆。
請問 OP 是否是傳承字形的愛好者?您使用的「新細明體」很可能是網絡上被網友魔改之後的 bug 字型文件哦(合不合法都是問題)。如果擁護傳承字形,可以用「一點字坊」製作的「一點明體」哦,鏈接:https://github.com/ichitenfont/I.Ming
关于 hinting,我怀疑您的理解有一点偏差。一般来说 hinting(可译作「渲染提示」)指的是字体栅格化时为使轮廓能够与像素对齐而做的一些修正与调整。首先,造字时并不会利用 hinting 去生成字形;其次,hinting 只在字体渲染(把轮廓字显示在像素网格上)时起作用,不会调整行高、间距这些东西,LaTeX/TeX 也不需要字体的 hinting 信息来生成 PDF。
参考:
看到以上回答,我希望在這裡能一次過回覆一下。 關於細明體/新細明體,對於 @RuixiZhang42 的疑問,示例中所用的版本為3.2,或者講是Windows XP內嵌細明體之同一代的華康字型。為何要使用該一舊版本之字體文件,原因眾多,包括授權等問題,也不必一一陳述。 華康字型的設計方式的確是與眾不同,對於 @stone-zeng 的評論,不是我的理解出現了偏差,而是(我自認為)華康濫用了 hinting 作為批量生產字型的模式,這種情況也見於其他的一些字體。詳細請參閱該字型文件或以下連結:Not Again, MingLiu!,詳述了其字型的設計方面的一些問題。 關於 @RuixiZhang42 的回覆來講,問題出在字體方面是非常大的,當然我也沒有認為這是 LaTeX 或者 CJK 宏集的問題,而是相當於提出疑問與希望尋求解決辦法。我明白所謂的渲染字框的意義,也做了不少測試,始終來講,我認為傳統 LaTeX 大多適應於西文排版的方面,所以有種希望中文宏包能解決更多問題的想法。所以我在此發佈 issue 的時候,其實希望能夠解決最重要的問題就是:我們能否把中文字的字深下溢修正過來,試圖把中文字系列規範到方格當中? 我認為此問題是可以被修正的,特別是當前的 XeLaTeX 等工具支持 TTF/OTF 渲染,hinting 等的一些重要特性卻缺乏完整的處理,因此這是值得討論研究的問題。
@GreenYun 有一招,但是非常危險:
\lineskiplimit=-\maxdimen
效果是 TeX 在任何情況下,都不會認為「兩行靠得太近」,所以行距會保持與 \baselineskip
相等。
使用新细明体 v3.21 + XeTeX 可以复现问题。XeTeX 使用 FreeType,而 LuaTeX/pTeX 系不用,因此可以考虑换其他引擎来处理:
\input expl3-generic
\input iftex.sty
\ifxetex
\font\mingliu="[mingliu.ttc]" at 25pt
\noindent
Engine: xetex
\fi
\ifluatex
\input luaotfload.sty
\font\mingliu="file:mingliu.ttc" at 25pt
\noindent
Engine: luatex
\fi
\ifptexng
\special{pdf:mapline upserif-h UniGB-UTF16-H mingliu.ttc}
\jfont\mingliu=upserif-h at 25pt
\noindent
Engine: ptex-ng
\fi
\mingliu
\ExplSyntaxOn
\noindent
\tl_map_inline:nn
{
觀自在菩薩,行深般若波羅蜜多時,照見五蘊皆空,度一切苦厄。舍利子,
色不異空,空不異色;色即是空,空即是色。受、想、行、識,亦復如是。舍
利子,是諸法空相,不生不滅,不垢不淨,不增不減,是故空中無色,無受、
想、行、識;無眼、耳、鼻、舌、身、意;無色、聲、香、味、觸、法;無眼
界,乃至無意識界;無無明,亦無無明盡;乃至無老死,亦無老死盡。無苦、
集、滅、道,無智亦無得,以無所得故。菩提薩埵,依般若波羅蜜多故,心無
罣礙,無罣礙故,無有恐怖,遠離顛倒夢想,究竟涅槃。三世諸佛,依般若波
羅蜜多故,得阿耨多羅三藐三菩提。故知般若波羅蜜多,是大神咒,是大明
咒,是無上咒,是無等等咒,能除一切苦,真實不虛。故說般若波羅蜜多咒,
即說咒曰:揭諦揭諦,波羅揭諦,波羅僧揭諦,菩提薩婆。
}
{ #1 \hskip 0pt plus 0.08\baselineskip \relax }
\ExplSyntaxOff
\bye
CTeX 宏集也支持这些引擎,不妨尝试一下。
感謝各位的耐心指導,我會研究一下各種方案。
一些字體(猶如細明體,思源也有該問題然而不明顯)通過使用 Hinting 程式以合成中文字,Hinting 引起中文文本字高不一,使得行距不一,不符合一般中文排版習慣。在此想請教一下是否有妥善的解決方案?