Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

破折号合字与 U+2E3A 的问题 #11

Closed
RuixiZhang42 opened this issue Apr 2, 2019 · 18 comments
Closed

破折号合字与 U+2E3A 的问题 #11

RuixiZhang42 opened this issue Apr 2, 2019 · 18 comments
Assignees
Milestone

Comments

@RuixiZhang42
Copy link

发现 U+2E3A Two-Em Dash 码位上的字形有误,仅占一个字宽,应将其改为占两个字宽的一条横杠。

另外,可否添加两项 OpenType 的「字形组合」ccmp 特性:若遇到两个连续的 U+2014 字符或者遇到两个连续的 U+2015 字符,就将字形替换成 U+2E3A?目前「思源」系列就是采用这种方法,可以保证破折号中间不断开(毕竟是因为连成了一个符号)。

从设计上来看,U+2E3A 虽然「占位」两个字,但是最好不要「顶格」,两端留出适量空白,排版效果更佳。Type is Beautiful 最近的文章 《不离不弃的破折号》 里有更多细节,其中关于两端留白就提到了「表里如一——一一分辨」这个例子。

@SyaoranHinata
Copy link
Contributor

SyaoranHinata commented Apr 19, 2019

您好,首先謝謝閣下的意見。

我們在I.Ming 5.1版本公佈後,曾收到有關破折號的意見,當時並沒有朋友提及需要佔用兩個二寬的U+2E3A,因此我們並沒有這樣處理。I.Ming 6.0公佈於2018年12月27日,而Type is Beautiful的文章發佈於2019年3月13日。我們並不能未占先知,知道大家在未來的需求。

當然,現在閣下提供意見了,我們日後會認眞考慮。第一層目標是把U+2E3A處理成兩個字寬的橫線。要是第一層目標成功,那麼第二層目標是再利用OpenType特性作進一步的自動變換。然而,我只能說認眞考慮,不能保證必定會提供。因爲我們的目標,是提供符合傳承字形字樣的字型,標點卻不是我們的主力及擅長範圍。本身我們的專門處理範圍在於漢字字形,我們並不懂得寫程式或應付因程序而生的問題。在6.0版本發佈前,我們就只因爲十數個標點問題,被OpenType技術(對,正正就是OpenType技術)等不斷折磨又折磨,擺平了一個問題卻又自動生了另外的問題,反來覆去,浪費了很大量的時間,令我們丟下了確保字形一致正確的本業,白白推遲了新版的面世時間。

因此,我們對於漢字字形以外的問題,只能說盡力而爲,但絕對無法作任何承諾。若閣下或各位網友擅長處理甚麼OpenType特性之類的這方面,在下強烈希望您能加入我們的工作團隊。先行拜謝!

@RuixiZhang42
Copy link
Author

非常感謝您的正面答應!不知您的團隊是否是使用 FontForge 軟件 開發一點明體。若是,那麼我可以為您的團隊提供一些解決方案。

我對一點明體 6.00 版本做了如下修改:

  1. 修正 em dash(U+2014)之名稱;
  2. 刪除 two-em dash(U+2E3A)之錯誤字形;
  3. 通過複製、粘貼、變形 em dash(U+2014)之字形,繪製正確的 two-em dash(U+2E3A)與 three-em dash(U+2E3B);
  4. 添加 GSUB 之 ccmp 特性,使得用戶連續輸入兩個 em dash(U+2014)或是兩個 horizontal bar(U+2015)時,能夠自動替換成 two-em dash(U+2E3A),不僅更好看,還能保證中間不斷開。相似地,若是連續輸入三個,則能自動替換成 three-em dash(U+2E3B)。

修改後的字型文件暫時命名為 I.Ming-6.01.ttf,全部通過 FontForge 實現。以下我將詳細說明修改的步驟。

修正 em dash(U+2014)之名稱

  • 用 FontForge 打開 I.Ming-6.00.ttf 之後,定位到 em dash(U+2014),可見紅色圓圈內名稱錯誤:
    step1-1

  • 選中該字符,右鍵打開菜單,點擊 Glyph Info
    step1-2

  • 在跳出的界面框內,點擊 Set From Name,即可自動修正字符之名稱:
    step1-3

  • 點擊 OK,退回到先前界面,可見綠色圓圈內名稱正確:
    step1-4

刪除 two-em dash(U+2E3A)之錯誤字形

  • 接下來定位到 two-em dash(U+2E3A),選中該字形並將它複製下來,以便之後粘貼。
    step2-1

  • 在任務欄中點擊 Encoding,並在展開的餐單中點擊 Detach & Remove Glyphs
    step2-2

  • 在跳出的界面框內,點擊 Remove
    step2-3

  • 效果如下:
    step2-4

繪製正確的 two-em dash(U+2E3A)與 three-em dash(U+2E3B)

  • 將上一步裡驟複製下來的字形粘貼到該碼位上。
    step3-1

  • 順便把隔壁的 three-em dash(U+2E3B)也粘貼一份。
    step3-2

  • 接下來為這兩個新增的字形命名。先做 U+2E3A,通過右鍵打開菜單、點擊 Glyph Info,在跳出的界面框內,在如下位置輸入 uni2E3A
    step3-3

  • 點擊 Set From Name 完成自動填充。
    step3-4

  • 別忘了點擊 OK。然後對隔壁的 U+2E3B 做相同的處理,這回輸入的是 uni2E3B
    step3-5

  • 效果如下:
    step3-6

  • 現在開始重繪字形:雙擊 U+2E3A 打開字形編輯界面,在任務欄裡點擊 Metrics 並在展開菜單裡點擊 Set Width,在 Scale Width By 那裡輸入 200
    step3-7

  • 然後用 Ctrl + A 的方式全選整個字形,接著,在任務欄裡點擊 Element,展開菜單裡點擊 Transformations,然後再選擇 Non Linear Transformation,在 X Expr 那裡輸入 x*1.85546875
    step3-8

  • 最後,在任務欄 Metrics 下拉菜單裡點擊 Center in Width,將字形居中對齊,最終效果如下:
    step3-9

  • 重繪隔壁的 U+2E3B,步驟一致。不過 Scale Width By 那裡要輸入 300、全選字形變形時 X Expr 那裡要輸入 x*2.85546875、最後居中對齊,效果如下:
    step3-10

@RuixiZhang42
Copy link
Author

這裡可能需要說明一下為什麼我選擇 1.855468752.85546875 這兩個數,這個是我仿照相似字重的思源宋體 Regular 與 Medium 算出來的數值,小數點這麼多是因為一點明體用的 Unit Per Em 是 2048。這兩個數等價於設置了 U+2E3A 字面寬 3800(兩邊留白各 148)、U+2E3B 字面寬 5848(兩邊留白也是各 148)。

最後就是 OpenType 特性啦!

添加 GSUB 之 ccmp 特性

  • 繪製好正確的字形後,退回到字型文件界面,點擊任務欄的 Element,然後點擊 Font Info 打開字型信息:
    step4-1

  • 在跳出的界面左側,可以看到 Lookups 這一項,點擊後在右側出現 GSUB 特性表,展開 ccmp 裡面的東西,然後雙擊打開它:
    step4-2

  • 跳出來新界面 Lookup Subtable, 'ccmp' ...,拉到最下面,可以看到有個 <New>,連點四次,創建四個新的特性指令:
    step4-3

  • 在如下位置輸入 uni2E3 然後通過自動填充的辦法補全 uni2E3A(圖)
    step4-4

  • 在旁邊一欄輸入 emdas 然後自動填充補全 emdash(圖),打一個空格,緊接著再自動補全一個 emdash(圖)
    step4-5

  • 然後可以填寫下一欄,左邊自動補全 uni2E3B(圖),右邊則是 emdash(圖)<空格>emdash(圖)<空格>emdash(圖)
    step4-6

  • 為了支持 U+2015 也能自動替換(TIB 那篇文章說日本那邊習慣用 U+2015 來表示破折號?),可以仿照上面填寫 U+2015 版本的 U+2E3A 與 U+2E3B:
    step4-7

  • 點擊 OK 之後退回到字型文件界面,現在就可以導出新的字型文件了!在任務欄點擊 File,然後點擊 Generate Fonts,填寫、勾選如下信息即可生成 I.Ming-6.01.ttf
    step4-8

@RuixiZhang42
Copy link
Author

RuixiZhang42 commented Apr 21, 2019

我對新生成的字型做了測試,也歡迎您有空也測試一下。我沒有商業軟件例如 Adobe InDesign,所以我是在 XeLaTeX 裡進行的測試,下面我附上 I.Ming-6.01.ttf 的輸出結果,同時還附上 PDF 用於對比。

I Ming-6 00-result

I Ming-6 01-result

以下是測試源代碼:

% !TeX program = XeLaTeX
\documentclass{article}
\usepackage{fontspec}
\setmainfont{[I.Ming-6.01.ttf]}
\begin{document}
通過「正常輸入法」輸入破折號的效果:\par
美圖—國家\par
美圖——國家\par
美圖———國家

\medskip

測試新字型文件能否處理 Unicode 編碼輸入:\par
美圖\char"2014 國家\par
美圖\char"2014 \char"2014 國家\par
美圖\char"2014 \char"2014 \char"2014 國家

美圖\char"2015 國家\par
美圖\char"2015 \char"2015 國家\par
美圖\char"2015 \char"2015 \char"2015 國家
\end{document}

P.S. 更多對比效果,上為 I.Ming-6.00,下為 I.Ming-6.01:

compare

@SyaoranHinata
Copy link
Contributor

感謝你的詳細留意,但內容相當複雜,我們需要消化理解一下。我們內部也有些試作版本,但因爲尚有問題無法公開。不知閣下是否方便電郵至 ichitenfont★gmail.com 商議?感謝!

@creatxrgithub
Copy link

@RuixiZhang42

FontForge 打開 6.00 版 TTF 文,會發現有好多字丟失編碼,不知怎麼解決?謝謝

@SyaoranHinata
Copy link
Contributor

樓上朋友的FontForge版本是否有點問題?有沒嘗試過更換不同的版本?

@creatxrgithub
Copy link

Screenshot_2019-06-05_23-56-18

使用轉換後的 SVG 文件就明顯好多丟失編碼(丟失編碼的都集中在前部了)

Screenshot_2019-06-05_23-53-50

windows 和 linux 下的 fontforge 都試過了

@RuixiZhang42
Copy link
Author

@creatxrgithub 應該是 FontForge 的問題,我用的是 2017 年 7 月 31 日的版本,不存在編碼缺失的情況。不過,您這個問題不適合在這裡討論,它屬於 FontForge 軟件的問題,與一點明體「字型 repository」無關。

@groverlynn
Copy link

U+2E3A Two-Em Dash並非破折號,而是缺字號,在西文排版中用來表示此處有字但因汙損等原因缺失

@NightFurySL2001
Copy link

NightFurySL2001 commented Jun 8, 2023

U+2E3A Two-Em Dash 如同issue首po所链接的 https://www.thetype.com/2019/03/14918/ 文章,形态上是符合中文破折号的要求(不断开的占两em的横线),且思源黑体也如此操作,并无不妥。英文除了缺字符也有相似破折号的使用方法,因此语义上也没有问题。(Unicode一般只按形定义,鲜少为语义定义)请参考 https://en.wikipedia.org/wiki/Dash#Spacing_and_substitution

另,此字符已经在 7.100 起制作完成。

@groverlynn
Copy link

U+2E3A Two-Em Dash 如同issue首po所链接的 https://www.thetype.com/2019/03/14918/ 文章,形态上是符合中文破折号的要求(不断开的占两em的横线),且思源黑体也如此操作,并无不妥。英文除了缺字符也有相似破折号的使用方法,因此语义上也没有问题。(Unicode一般只按形定义,鲜少为语义定义)请参考 https://en.wikipedia.org/wiki/Dash#Spacing_and_substitution

另,此字符已经在 7.100 起制作完成。

unicode  

U+2E3A Two-Em Dash 如同issue首po所链接的 https://www.thetype.com/2019/03/14918/ 文章,形态上是符合中文破折号的要求(不断开的占两em的横线),且思源黑体也如此操作,并无不妥。英文除了缺字符也有相似破折号的使用方法,因此语义上也没有问题。(Unicode一般只按形定义,鲜少为语义定义)请参考 https://en.wikipedia.org/wiki/Dash#Spacing_and_substitution

另,此字符已经在 7.100 起制作完成。

形態上只是「接近」中文破折號的要求而已,但並不完全「符合」。中文破折號應該是長兩個字身(但絕不撐滿兩個字面)且位於字面半身。漢字的字身略小於字面,字面的高對應鉛字的1em,所以直排時破折號高度大約1.9em。漢字的字寬一般略小於字高,所以破折號橫排時寬度應該不超過1.8em。而U+2E3A必須撐滿2em且不留字距。
unicode的East Asian Width字寬屬性,U+2E3A是neutral(無對應全寬字符的自然窄字符)。與西文共用的標點必須是ambiguous(可寬可窄)。U+2E3A之所以是窄字符,是因為它理應對應四個漢字字身寬的符號
語義上與中文破折號相同的西文標點只有長破折號(em dash)和引用破折號(quotation dash即horizontal bar)

@NightFurySL2001
Copy link

NightFurySL2001 commented Jun 13, 2023

形態上只是「接近」中文破折號的要求而已,但並不完全「符合」。中文破折號應該是長兩個字身(但絕不撐滿兩個字面)且位於字面半身。漢字的字身略小於字面,字面的高對應鉛字的1em,所以直排時破折號高度大約1.9em。漢字的字寬一般略小於字高,所以破折號橫排時寬度應該不超過1.8em。

注意:这边的描述是由字型处理,和是否应该选用 U+2E3A 完全无关。本字体内 U+2E3A 字形宽度是 2 个汉字宽度(中文内等于2em),左右有略微空隙,符合破折号的排版需求。

image

而U+2E3A必須撐滿2em且不留字距。

西文字体内并没有硬性规定 U+2E3A 必须撑满 2em。虽然系统内建多数是撑满,但是也有字体(如Android系统字体Roboto)是做成不占满,而 Times New Roman 的 U+2E3A 完全超过 2em。

unicode的East Asian Width字寬屬性,U+2E3A是neutral(無對應全寬字符的自然窄字符)。

U+2E3A 在 UAX #11 East Asian Width(东亚宽度属性) 内是 neutral 没错,但是 neutral 并不是“无对应全宽字符的自然窄字符”,这是错误理解。请参考 UAX #11 原文:

ED7. Neutral (Not East Asian): All other characters. Neutral characters do not occur in legacy East Asian character sets. By extension, they also do not occur in East Asian typography. For example, there is no traditional Japanese way of typesetting Devanagari.
中性(非东亚): 所有其他字符。中性字符不出现在历史东亚字符集中。推而广之,它们也不会出现在东亚的字体设计中。例如,日本没有传统的Devanagari排版方式。

Neutral 仅代表这个字符不在历史东亚字符集中(如 Big5、CNS11643、GB/T 2312、JIS X 0208 等)使用而已。在现代排版需求下(且更多跨语言和更多符合语义的新字符),破折号使用 U+2E3A 并无不妥。选用原因如本 issue 首po提到的文章,相比于使用两个 U+2014 更好的原因如下:

  • 中间是连接的(U+2014 在部分字体左右有空隙,尤其是历史的东亚字符集都是有空隙而不是撑满的导致破折号中间有空隙)
  • 不会有中间断开的情况(视排版系统支援程度)

如果在 UAX #11 中继续搜索 neutral 也会发现是有字体制作成全宽、排版系统显示成全宽的情况:

Conversely, many of the symbols in the Unicode Standard have no mappings to legacy character sets, yet they may be rendered as “wide” characters if they appear in an East Asian context. An implementation might therefore elect to treat them as ambiguous even though they are classified as neutral here.
相反,Unicode标准中的许多符号没有与历史字符集的映射关系,但如果它们出现在东亚语境中,就可能被呈现为 wide 字符。因此,一个实施方案可能会选择将它们视为 ambiguous,即使它们在这里被归类为 neutral。

與西文共用的標點必須是ambiguous(可寬可窄)。

同上,理解错误。Ambiguous 是可宽可窄,但是范围只限历史字符集中出现过的标点符号。新收录的字符即使是给中文(包括注音)使用也有 neutral 的情况,比如给闽南语方音符号用的阴去(U+02EA,˪)和阳去(U+02EB,˫)都是 neutral 而不是 ambiguous。

U+2E3A之所以是窄字符,是因為它理應對應四個漢字字身寬的符號

错误。如上所说,U+2E3A不是窄字符。另外,中文界的大致认同是一个汉字字身宽度是 1 个 em。查看历史字符集,Big5、GB/T 2312 和 JIS X 0208 都是把一个汉字宽度的一字线对应到 U+2014 — EM DASH,也间接证明 1 em = 1个汉字字身宽度。U+2E3A 正如其名 TWO EM DASH 就是 U+2014 的双倍宽度。无论中文西文字体内的 U+2E3A 都是 U+2014 的两倍宽度,因此 U+2E3A 对应的是两个汉字字身宽度的符号,正好符合破折号的要求。

語義上與中文破折號相同的西文標點只有長破折號(em dash)和引用破折號(quotation dash即horizontal bar)

请阅读上述维基百科链接 https://en.wikipedia.org/wiki/Dash#Spacing_and_substitution:

A section on the 2-em rule (⸺) also explains that the 2-em can be used to mark an abrupt break in direct or reported speech, ...
关于2-em规则(⸺)的一节还解释说,2-em可以用来标记直接或报告中的突然中断,...

此处使用场景和台湾教育部《重订标点符号手册》中破折号的“或在行文中为补充说明某词语之处,而此说明后文气需要停顿。”语义相近。

@groverlynn
Copy link

形態上只是「接近」中文破折號的要求而已,但並不完全「符合」。中文破折號應該是長兩個字身(但絕不撐滿兩個字面)且位於字面半身。漢字的字身略小於字面,字面的高對應鉛字的1em,所以直排時破折號高度大約1.9em。漢字的字寬一般略小於字高,所以破折號橫排時寬度應該不超過1.8em。

注意:这边的描述是由字型处理,和是否应该选用 U+2E3A 完全无关。本字体内 U+2E3A 字形宽度是 2 个汉字宽度(中文内等于2em),左右有略微空隙,符合破折号的排版需求。

em是字高(行高)的單位,而非字寬的單位。漢字鉛字的字寬是略小於字高的,數碼字體也不一定要讓漢字字寬等於1 em。視乎字體風格,隸書字寬應大於字高,行書字寬應略小於字高。篆書字寬則可能爲字高的一半。

image

而U+2E3A必須撐滿2em且不留字距。

西文字体内并没有硬性规定 U+2E3A 必须撑满 2em。虽然系统内建多数是撑满,但是也有字体(如Android系统字体Roboto)是做成不占满,而 Times New Roman 的 U+2E3A 完全超过 2em。

unicode的East Asian Width字寬屬性,U+2E3A是neutral(無對應全寬字符的自然窄字符)。

U+2E3A 在 UAX #11 East Asian Width(东亚宽度属性) 内是 neutral 没错,但是 neutral 并不是“无对应全宽字符的自然窄字符”,这是错误理解。请参考 UAX #11 原文:

ED7. Neutral (Not East Asian): All other characters. Neutral characters do not occur in legacy East Asian character sets. By extension, they also do not occur in East Asian typography. For example, there is no traditional Japanese way of typesetting Devanagari.
中性(非东亚): 所有其他字符。中性字符不出现在历史东亚字符集中。推而广之,它们也不会出现在东亚的字体设计中。例如,日本没有传统的Devanagari排版方式。

不出现在历史东亚字符集中 => 無對應全寬字符。自然窄字符的對應全寬字符只出現於歷史東亞字符集,而所有出現於歷史東亞字符集的自然窄字符全部有對應的全寬字符(至少在一個歷史東亞字符集中出現)。
天城文未出現於任何東亞歷史字符集中,也就沒有對應全寬字符。
反過來,emoji從未出現在任何東亞歷史字符集中,但一律爲自然寬字符。
而定義爲neutral的還有ascii控制字符(0x0–0x1F),它們是全數收錄於所有東亞歷史字符集中的。大量的非基本拉丁字母(比如ç、ü)也是定義爲neutral,但是收錄於GBK等東亞字符集中。

Neutral 仅代表这个字符不在历史东亚字符集中(如 Big5、CNS11643、GB/T 2312、JIS X 0208 等)使用而已。在现代排版需求下(且更多跨语言和更多符合语义的新字符),破折号使用 U+2E3A 并无不妥。选用原因如本 issue 首po提到的文章,相比于使用两个 U+2014 更好的原因如下:

  • 中间是连接的(U+2014 在部分字体左右有空隙,尤其是历史的东亚字符集都是有空隙而不是撑满的导致破折号中间有空隙)
  • 不会有中间断开的情况(视排版系统支援程度)

如果在 UAX #11 中继续搜索 neutral 也会发现是有字体制作成全宽、排版系统显示成全宽的情况:

Conversely, many of the symbols in the Unicode Standard have no mappings to legacy character sets, yet they may be rendered as “wide” characters if they appear in an East Asian context. An implementation might therefore elect to treat them as ambiguous even though they are classified as neutral here.
相反,Unicode标准中的许多符号没有与历史字符集的映射关系,但如果它们出现在东亚语境中,就可能被呈现为 wide 字符。因此,一个实施方案可能会选择将它们视为 ambiguous,即使它们在这里被归类为 neutral。

與西文共用的標點必須是ambiguous(可寬可窄)。

同上,理解错误。Ambiguous 是可宽可窄,但是范围只限历史字符集中出现过的标点符号。新收录的字符即使是给中文(包括注音)使用也有 neutral 的情况,比如给闽南语方音符号用的阴去(U+02EA,˪)和阳去(U+02EB,˫)都是 neutral 而不是 ambiguous。

音調符號並非象形文字,也不能單獨成字,所以從來都不是寬字符。ascii中的幾個音調符號是narrow,因爲有全寬版本。ascii之外的音調符號則是neutral。unicode對此有專門說明(ED6後半部分)。而且音調符號不是標點,而屬於文字的附加部分。必須可寬可窄的是標點

U+2E3A之所以是窄字符,是因為它理應對應四個漢字字身寬的符號

错误。如上所说,U+2E3A不是窄字符。另外,中文界的大致认同是一个汉字字身宽度是 1 个 em。查看历史字符集,Big5、GB/T 2312 和 JIS X 0208 都是把一个汉字宽度的一字线对应到 U+2014 — EM DASH,也间接证明 1 em = 1个汉字字身宽度。U+2E3A 正如其名 TWO EM DASH 就是 U+2014 的双倍宽度。无论中文西文字体内的 U+2E3A 都是 U+2014 的两倍宽度,因此 U+2E3A 对应的是两个汉字字身宽度的符号,正好符合破折号的要求。

恰好符合不代表就是正確合理。就如全寬置中的句點不可以用作間隔號,即便不少字體採用相同的glyph(從字體角度完全沒有問題),但是語義上就是完全錯誤的。

語義上與中文破折號相同的西文標點只有長破折號(em dash)和引用破折號(quotation dash即horizontal bar)

请阅读上述维基百科链接 https://en.wikipedia.org/wiki/Dash#Spacing_and_substitution:

A section on the 2-em rule (⸺) also explains that the 2-em can be used to mark an abrupt break in direct or reported speech, ...
关于2-em规则(⸺)的一节还解释说,2-em可以用来标记直接或报告中的突然中断,...

此处使用场景和台湾教育部《重订标点符号手册》中破折号的“或在行文中为补充说明某词语之处,而此说明后文气需要停顿。”语义相近。

你所舉的是非常不常見的用法。同理也有人主張連用兩個破折號(四個漢字字身寬)來表達停頓的。

@NightFurySL2001
Copy link

NightFurySL2001 commented Jun 30, 2023

em是字高(行高)的單位,而非字寬的單位。漢字鉛字的字寬是略小於字高的,數碼字體也不一定要讓漢字字寬等於1 em。視乎字體風格,隸書字寬應大於字高,行書字寬應略小於字高。篆書字寬則可能爲字高的一半。

请注意:这边是一点明体 字型(字体文件) 的讨论区。本字体不是铅字字体,本字体的汉字字宽为1em。您所指的“字宽”,“字高”的专业学术词应该是“字面宽”,“字面高”。

image
https://zhuanlan.zhihu.com/p/28959063)
image
https://blog.justfont.com/2012/12/hanzi-type-design-1/)

另外补充回复上上上一个评论的误用:

中文破折號應該是長兩個字身(但絕不撐滿兩個字面)且位於字面半身。漢字的字身略小於字面,字面的高對應鉛字的1em,所以直排時破折號高度大約1.9em。在现代字体中代表 U+2E3A 的宽度在正文字体中是宽 2 em 的。

此处两个用词使用相反了。另外,参考上图,中日韩的 1 em 如我之前所说的是以字身高度为准,如果是正文铅字(正方形)那么字身宽度也是 1 em。直排时破折号 字面 高度是 1.9 em,但是 字身 (铅字)高度是完整 2 em,否则排版正文时会出现无法对齐的情况。

image
https://learn.justfont.com/pocketbook/chinese-typeface/anatomy/body)


不出现在历史东亚字符集中 => 無對應全寬字符。自然窄字符的對應全寬字符只出現於歷史東亞字符集,而所有出現於歷史東亞字符集的自然窄字符全部有對應的全寬字符(至少在一個歷史東亞字符集中出現)。
天城文未出現於任何東亞歷史字符集中,也就沒有對應全寬字符。
反過來,emoji從未出現在任何東亞歷史字符集中,但一律爲自然寬字符。
而定義爲neutral的還有ascii控制字符(0x0–0x1F),它們是全數收錄於所有東亞歷史字符集中的。大量的非基本拉丁字母(比如ç、ü)也是定義爲neutral,但是收錄於GBK等東亞字符集中。

您确认「emoji從未出現在任何東亞歷史字符集中」是正确的吗?

Emoji 是由日本电信公司所编码而成。其中 ARIB 基于 JIS X 0201 扩展,DoCoMo、KDDI、SoftBank 3G 则是基于 ShiftJIS 扩展。Unicode 正是由这些电信公司基于 JIS 编码扩展才会收录编码 emoji。在这些扩展中,emoji 都是按照双字节制作成全宽字符,因此 Unicode 才会把 emoji 当作 Wide 字符处理。UAX #11 的介绍部分也有同样解释:

In contrast, emoji characters were first developed through the use of extensions of legacy East Asian encodings, such as Shift-JIS, and in such a context they were treated as wide characters. While these extensions have been added to Unicode or mapped to standardized variation sequences, their treatment as wide characters has been retained, and extended for consistency with emoji characters that lack a legacy encoding.
相比之下,emoji字符最初是通过使用历史东亚编码(如Shift-JIS)的扩展来开发的,在这种情况下,它们被视为 Wide 字符。虽然这些扩展已经被添加到Unicode中,或者被映射到标准化的变体序列中,但它们作为 Wide 字符的处理方式被保留了下来,为了与缺乏历史编码的emoji字符保持一致而被扩展。

后续新编码的 emoji 按照 UAX#11 中的 ED4 定义,皆定义为 Wide。

请给出哪些历史东亚字符集有收录 ASCII 控制字符(0x0 - 0x1F)。

请注意:“ç”(U+00E7)未于 GBK 或任何其他历史东亚字符集中有收录,因此定义确实是 Neutral。“ü”(U+00FC)作为汉语拼音字母有在 GB 2312/GBK中收录,其 East Asian Width 是 Ambiguous (A) 而不是 Neutral (N)。


音調符號並非象形文字,也不能單獨成字,所以從來都不是寬字符。ascii中的幾個音調符號是narrow,因爲有全寬版本。ascii之外的音調符號則是neutral。unicode對此有專門說明(ED6後半部分)。而且音調符號不是標點,而屬於文字的附加部分。必須可寬可窄的是標點。

这个部分是我的失误,所提出的两个音调符号不是标点符号,也稍微偏题。但是,这两个符号(U+02EA,˪)和(U+02EB,˫)是较新 Unicode 中专为中文所编码的,其他参考的音调符号是注音符号(ㄓㄨˋ ㄧㄣ ㄈㄨˊ ㄏㄠˋ)使用的音调符号(ˊ,U+02CA)(ˇ,U+02C7)(ˋ,U+02CB)(˙,U+02D9)。这几个符号对应的 East Asian Width 是 Ambiguous,因为其在 Big5/GB 2312 中作为注音符号后续的标调,是需要呈现为全宽字符。但是即使(U+02EA,˪)和(U+02EB,˫)理应和其他音调符号作为注音符号后续的标调时呈现为全宽字符,他们的 East Asian Width 还是 Neutral。需要特别注明,此处说的“音调符号”指的是“占位修饰符号”(Spacing Modifier Letters)。

以上是示例即使是专门给中文使用的占位符号也不一定是 Ambiguous/Wide。使用这两个音调作为示例是因为中文标点符号多数已经在 Unicode 早期兼容 Big5/GBK/JIS X 0213,本人无法找到在 UAX#11 后新收入 Unicode 的中文标点符号。

另外,ED6 后半部分请问有哪一句说明 ASCII 外的音调符号必须是 Neutral?


恰好符合不代表就是正確合理。就如全寬置中的句點不可以用作間隔號,即便不少字體採用相同的glyph(從字體角度完全沒有問題),但是語義上就是完全錯誤的。

这边并不是恰好符合,而是形态上完全符合。需要注意全宽西文句号在日文、简体中文字体和 Unicode code charts 中默认是在左下角的,形态上并不符合间隔号。

另外, Unicode 也有众多语义上不同但是实际使用码位一样的情况。比如说,英文场景下数字用的千位分割符是西文逗号,而其他欧文场景下小数点使用的也是西文逗号。即使在两个语言中的语义不同,但并不影响 Unicode 把二者视为一样的 character(字符)。

Unification
It is quite normal for many characters to have different usages, such as comma “ , ” for either thousands-separator (English) or decimal-separator (French). The Unicode Standard avoids duplication of characters due to specific usage in different languages; rather, it duplicates characters only to support compatibility with base standards. Avoidance of duplicate encoding of characters is important to avoid visual ambiguity.
许多字符有不同的用途是很正常的,比如逗号“,”用于千位分隔符(英语)或小数分隔符(法语)。Unicode标准避免了由于不同语言中的特殊用法而导致的字符重复;相反,它重复字符只是为了支持与基础标准的兼容性。避免字符的重复编码对于避免视觉上的歧义非常重要。
Unicode 15.0, page 21 第21页

另外也有希腊文的问号使用西文分号、希腊文的分号使用西文中点号的情况,即使在不同语言有不同语义,还是使用同样的字符。

Compatibility Punctuations. Two specific modern Greek punctuation marks are encoded in the Greek and Coptic block: U+037E “;” GREEK QUESTION MARK and U+0387 “·” GREEK ANO TELEIA. The Greek question mark (or erotimatiko) has the shape of a semicolon, but functions as a question mark in the Greek script. The ano teleia has the shape of a middle dot, but functions as a semicolon in the Greek script.
These two compatibility punctuation characters have canonical equivalences to U+003B SEMICOLON and U+00B7 MIDDLE DOT, respectively; as a result, normalized Greek text will lose any distinctions between the Greek compatibility punctuation characters and the common punctuation marks. Furthermore, ISO/IEC 8859-7 and most vendor code pages for Greek simply make use of semicolon and middle dot for the punctuation in question. Therefore, use of U+037E and U+0387 is not necessary for interoperating with legacy Greek data, and their use is not generally encouraged for representation of Greek punctuation.
兼容性标点符号。 两个特定的现代希腊标点符号在希腊语和科普特语区段中被编码: U+037E “;” 希腊语问号和U+0387 “·” 希腊语 ano teleia。希腊语问号(或称 "erotimatiko")的形状为分号,但在希腊文中作为问号使用。ano teleia 的形状是一个中间的点,但在希腊文中作为分号使用。
这两个兼容性标点符号分别与U+003B分号和U+00B7中点号有正式的对应关系(canonical equivalences);因此,规范化的希腊文本将失去希腊兼容性标点符号和普通标点符号之间的任何区别。此外,ISO/IEC 8859-7和大多数供应商的希腊语代码页都简单地 使用了分号和中间点来表示有关的标点符号。 因此,使用U+037E和U+0387对于与传统希腊语数据的互操作是没有必要的,而且一般不鼓励使用它们来表示希腊语标点符号。
Unicode 15.0, page 308 第308页


你所舉的是非常不常見的用法。同理也有人主張連用兩個破折號(四個漢字字身寬)來表達停頓的。

我们并未赞同或反对其他人使用两个破折号的使用方法,他们有使用的权利,只要符合他们觉得该使用的方式使用即可。反而您在这里反对使用 U+2E3A TWO EM DASH 作为破折号使用,不知有何意义。另外,即使语言不同,英文 U+2E3A 也有同中文一样使用方式,语义上中文破折号使用 U+2E3A 并无问题。


最后做个总结 tl;dr:

  1. 此处建议您重新阅读理解 UAX #11: East Asian Width (https://www.unicode.org/reports/tr11/ )。UAX#11 第二章就有明确表示该附件并不是用于字体设计:

This annex gives general guidelines how to use this property. It does not provide rules or specifications of how this property might be used in font design or line layout, because, while a useful property for this purpose, it is only one of several character properties that would need to be considered.
本附件给出了如何使用这一属性的一般准则。它 没有提供如何在字体设计 或线性布局中使用该属性的规则或规范,因为尽管它是一个有用的属性,但它只是需要考虑的几个字符属性之一。

该附件也不会根据现代使用场景而变化:

While the specific assignments of property values for given characters may change over time, it is generally not intended to reflect evolving practice for existing characters.
虽然特定字符的属性值的具体分配可能会随着时间的推移而改变,但一般来说,它并不打算反映现有字符的不断发展的做法。

该附件也说明字型和排版引擎有覆盖 UAX#11 的权利(ED1):

However, the actual display width of a glyph is given by the font and may be further adjusted by layout.
然而,一个字形的实际显示宽度是由字体给出的,并且可以通过布局进一步调整。

因此,建议您不要拿着鸡毛当令箭要求字型必须“遵守” UAX#11 的分类制作字体、使用 Unicode 字符,毕竟 UAX#11 不是“绝对性”的,也不是在字体设计使用的。

  1. 此处建议您阅读 Unicode Core Specification (https://www.unicode.org/versions/Unicode15.0.0/UnicodeStandard-15.0.pdf ),前面 6 章有阐述 Unicode 收字用字的实际使用情况。
    其中的重点在 Unicode 收录的是抽象字符(abstract character),收录字符时是 不管语义的。
    即使您要看语义,英文分号和希腊文问号语义完全不同都可以用同一个字符 U+003B,更何况英文其中一个用法和中文破折号有接近使用方式的 U+2E3A?
  2. 建议您阅读本 issue 最开始的博文 《不离不弃的破折号》 (https://www.thetype.com/2019/03/14918/ ) 和 中文排版需求 clreq (https://www.w3.org/TR/clreq/ ) 了解为什么建议中文破折号使用 U+2E3A。

最后的最后声明:

  • 以上所有回复皆为本人的观点,不代表一点字坊。
  • 以上需要引用的内容皆已提供来源,请先查阅后再评论。
  • 一点明体的目标是依据《校检表》制作汉字字形;标点符号属于额外支援,并非本项目的主要关注点。
  • 一点明体中早已有 U+2E3A、U+2E3B 当作中文破折号(分别两个和三个汉字宽度),本人提供协助时只负责设置 OpenType 功能把两个 U+2014 EM DASH 的字形(glyph)替换成 U+2E3A 的字形。
  • 本人不赞同也不反对其他码位或形式的破折号。本人(给一点字坊)的建议是参考 思源黑体 的设置:使用 U+2E3A 作为中文破折号的标准字形(占两个汉字宽度),将常见使用的破折号形式——两个 U+2014——作连字替换(ligature)成 U+2E3A 的形式。在没有 OpenType 支援的环境下,两个 U+2014 EM DASH 可能不会出现替换,导致破折号中间出现断开的情况(U+2014 在中文字体中一般不会撑满字面)。
  • 本人不会再回复任何无根据实际引用来源的错误内容/认知。

@groverlynn
Copy link

您确认「emoji從未出現在任何東亞歷史字符集中」是正确的吗?

Emoji 是由日本电信公司所编码而成。其中 ARIB 基于 JIS X 0201 扩展,DoCoMo、KDDI、SoftBank 3G 则是基于 ShiftJIS 扩展。Unicode 正是由这些电信公司基于 JIS 编码扩展才会收录编码 emoji。在这些扩展中,emoji 都是按照双字节制作成全宽字符,因此 Unicode 才会把 emoji 当作 Wide 字符处理。UAX #11 的介绍部分也有同样解释:

In contrast, emoji characters were first developed through the use of extensions of legacy East Asian encodings, such as Shift-JIS, and in such a context they were treated as wide characters. While these extensions have been added to Unicode or mapped to standardized variation sequences, their treatment as wide characters has been retained, and extended for consistency with emoji characters that lack a legacy encoding.
相比之下,emoji字符最初是通过使用历史东亚编码(如Shift-JIS)的扩展来开发的,在这种情况下,它们被视为 Wide 字符。虽然这些扩展已经被添加到Unicode中,或者被映射到标准化的变体序列中,但它们作为 Wide 字符的处理方式被保留了下来,为了与缺乏历史编码的emoji字符保持一致而被扩展。

四家日本電訊公司都是基於JIS擴展,但同一個擴展碼位對應的emoji完全不同,所以本質上就是將未編碼的shift JIS區域當作私用區,和webdings、wingdings等字體(後續也有不少演變成emoji)、網頁和操作系統的各類功能圖標字體是完全一樣的。在unicode對其正式編碼之前,emoji沒有納入任何一種編碼中。

后续新编码的 emoji 按照 UAX#11 中的 ED4 定义,皆定义为 Wide。

请给出哪些历史东亚字符集有收录 ASCII 控制字符(0x0 - 0x1F)。

(shift) JIS(不考慮shift的兩個字符,相同碼位兼容全部128個ASCII字符)。GB2312(相同碼位兼容全部128個ASCII字符)。Big5(控制字符轉移到A3C0 - A3E0)。KSC5636(除韓圓符號外,相同碼位兼容全部128個ASCII字符)。

以上是示例即使是专门给中文使用的占位符号也不一定是 Ambiguous/Wide。使用这两个音调作为示例是因为中文标点符号多数已经在 Unicode 早期兼容 Big5/GBK/JIS X 0213,本人无法找到在 UAX#11 后新收入 Unicode 的中文标点符号。

注音符號不是「中文」,其調號更是完全仿照拉丁字母設計的,後續新增的為閩客等語言註音的調號更是儘量符合IPA規則,而IPA是完完全全基於拉丁字母(及與拉丁字母有同源的希臘和希伯來字母)的。而同樣源自方塊字的片假名則一早就有半寬版本。這些拼音文字採用的規則和象形漢字並不完全相同。

这边并不是恰好符合,而是形态上完全符合。需要注意全宽西文句号在日文、简体中文字体和 Unicode code charts 中默认是在左下角的,形态上并不符合间隔号。

寬度不一樣,基線也不一樣,所以高度也不一樣……

另外, Unicode 也有众多语义上不同但是实际使用码位一样的情况。比如说,英文场景下数字用的千位分割符是西文逗号,而其他欧文场景下小数点使用的也是西文逗号。即使在两个语言中的语义不同,但并不影响 Unicode 把二者视为一样的 character(字符)。

但凡unicode設計成可混用的標點,其換行等屬性都能夠兼容。2-em dash可以放在行首(也就是在符號之前斷行),但破折號不可以(除非破折號在句首)。

@NightFurySL2001
Copy link

NightFurySL2001 commented Jul 6, 2023

四家日本電訊公司都是基於JIS擴展,但同一個擴展碼位對應的emoji完全不同,所以本質上就是將未編碼的shift JIS區域當作私用區,和webdings、wingdings等字體(後續也有不少演變成emoji)、網頁和操作系統的各類功能圖標字體是完全一樣的。在unicode對其正式編碼之前,emoji沒有納入任何一種編碼中。

即使如何,emoji还是来源于Wide属性的编码集,在Shift JIS 扩展内还是当成Wide处理,UAX #11 设定其为Wide并无问题。

(shift) JIS(不考慮shift的兩個字符,相同碼位兼容全部128個ASCII字符)。GB2312(相同碼位兼容全部128個ASCII字符)。Big5(控制字符轉移到A3C0 - A3E0)。KSC5636(除韓圓符號外,相同碼位兼容全部128個ASCII字符)。

JIS 系列中只有 JIS X 0201 的映射表是明确收录 ASCII 控制字符(0x0 - 0x1F),而实践该编码集的字体一般当成 Narrow 处理;其他部分并没有汉字表示。JIS X 0208/0213/Shift JIS 等其他字符集只负责多字节编码,可以兼容不代表他们收录了。GB 2312同理,只有双字节字符。KSC 5636 是同等 ISO 646 没错,但是也是没有汉字/谚文表示,全部字符都是 Narrow;双字节表由 KSC 5601处理。

至于 Big5,根据 Unicode 映射表(https://ftp.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT ),0xA3C0 至 0xA3E0 是未定义的。目前网上能找到把 0xA3C0 至 0xA3E0 对应到 ASCII 控制字符的只有 Big5-2003 (https://moztw.org/docs/big5/table/big5_2003-b2u.txt ),但是并不是对应到 U+0000..U+001F,而是对应 U+2400..U+241F(有看得到的字形)。Big5-2003 相对比较新,因此 UAX#11 并未考虑,U+2400..U+241F 仍旧是 Neutral。

当然这边讨论的重点中我忽略了一个最重要的问题:ASCII 控制字符是没有图像显示的,自然不可能将其定义为 Wide 或 Narrow。UAX#11 将其作为Neutral是回退机制,所有不在历史东亚编码集的字符默认都是 Netrual。

寬度不一樣,基線也不一樣,所以高度也不一樣……

如果按这个说辞,简体中文不应该和西文共用引号,因为宽度、基线、高度都不一样。实际上如同上面所说,Unicode 不定义字形 (glyph) 只定义字符 (character),宽度高度基线不一样不能作为阻止破折号使用 U+2E3A 的原因。这个问题正是需要字体来处理,因此简体中文字体的蝌蚪引号做成全宽,而本字体的 U+2E3A 做成两个汉字宽度的中文破折号。

但凡unicode設計成可混用的標點,其換行等屬性都能夠兼容。2-em dash可以放在行首(也就是在符號之前斷行),但破折號不可以(除非破折號在句首)。

如果你是指 Unicode 内的 UAX #14 Line Breaking Algorithm(换行算法),U+2014 和 U+2E3A 都是属于 B2 类,即允许前后都允许断开,因此此处您的表述在 Unicode 所定义范围内是错误的,U+2014 是可以在行首出现的。现实中你看到 U+2014 不会出现在行首多数情况下是排版引擎帮你设定好避头尾的设定(即覆盖 UAX#14),不是 Unicode 所定义;目前的排版引擎多数还是不支援 U+2E3A 的断行,因为clreq 还未被厂商实践在软件里面。

反而现实世界中 没有 完整实践 UAX#14 的排版引擎更多,使用两个 U+2014 还可以在中间断行的情况非常常见,使用稳定不会断开的 U+2E3A 比 两个 U+2014 更加接近排版需求(不断开比避头尾更重要)。


最后声明,这个计划只负责制作字体,我们所设定的码位都是基于其他建议或需求而设定,也不会无端使用没有前车之鉴的设定。把 U+2E3A 作为中文破折号使用有 clreq (排版需求)和思源黑体(字体制作,和本仓库一样)作为示例,我们也只是跟着目前最佳实践(current best practice)制作。如果还有关于 U+2E3A 和中文破折号的使用问题,建议您前往 clreq 的仓库提交讨论https://github.com/w3c/clreq/issues ),没有必要在这里继续讨论。

@groverlynn
Copy link

JIS 系列中只有 JIS X 0201 的映射表是明确收录 ASCII 控制字符(0x0 - 0x1F),而实践该编码集的字体一般当成 Narrow 处理;其他部分并没有汉字表示。JIS X 0208/0213/Shift JIS 等其他字符集只负责多字节编码,可以兼容不代表他们收录了。GB 2312同理,只有双字节字符。KSC 5636 是同等 ISO 646 没错,但是也是没有汉字/谚文表示,全部字符都是 Narrow;双字节表由 KSC 5601处理。

子集收錄ASCII控制字符,反而母集不收錄?請回中學複習集合的定義。
兼容即是「照抄」成子集,不會出現亂碼。unicode完全兼容ASCII。

当然这边讨论的重点中我忽略了一个最重要的问题:ASCII 控制字符是没有图像显示的,自然不可能将其定义为 Wide 或 Narrow。UAX#11 将其作为Neutral是回退机制,所有不在历史东亚编码集的字符默认都是 Netrual。

明明就是為了兼容全寬拉丁字母和半寬假名所以保留了Fullwidth及其源字符NarrowHalfwidth三種字寬屬性,方塊字歸入Wide、混用標點歸入Ambiguous,其餘不定義字寬亦即Neutral。一定是有Fullwidth分身,自身才能是narrow。一定是寬文本和比例文本都用得到才會是ambiguous。

如果按这个说辞,简体中文不应该和西文共用引号,因为宽度、基线、高度都不一样。实际上如同上面所说,Unicode 不定义字形 (glyph) 只定义字符 (character),宽度高度基线不一样不能作为阻止破折号使用 U+2E3A 的原因。这个问题正是需要字体来处理,因此简体中文字体的蝌蚪引号做成全宽,而本字体的 U+2E3A 做成两个汉字宽度的中文破折号。

簡中的彎引號與西文共用導致某些中文字體顯示中西文混排文本的時候慘不忍睹。單憑引號的前後兩個字符根本無法100%準確判斷該使用寬還是窄引號。何況大部分字體根本只有一個字寬版本。這個問題根本不該由字體來處理。由字體來處理實屬亡羊補牢。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants