觀此回答有感https://www.zhihu.com/answer/1215083944比如在電腦上按照某種字體把現在常用的漢字疊著寫出來,最後是否會是一個黑方塊
觀此回答有感https://www.zhihu.com/answer/1215083944
比如在電腦上按照某種字體把現在常用的漢字疊著寫出來,最後是否會是一個黑方塊
這個實驗我和 colourphilosophy 探討過,雖然看起來非常無厘頭,但其實對中文字體設計是有一些幫助的。
中文字體設計中有兩個概念:字身框和字面框。字身框是外側的方框,大致相當于田字格的外框,也相當於鉛活字那一個金屬方塊的大小;字面框則是漢字字元實際分布的空間,很大程度上能夠反應字體的特性。
所以,一般來說,即使把所有漢字疊加起來,字面框有可能會被填滿,但字身框中無論如何都還會留有一點空間,否則所有的漢字在排版時都會連在一起,沒有「呼吸的感覺」(笑)。
接下來我們看看真實字體的疊加情況。
我們把 GB2312 裡面的漢字隨機分了 10 組,然後分別疊加(全疊一起就是一坨黑,當然也可以後期加工)。在大樣本下每組基本沒什麼差別,換句話說疊加 600 字和 6000 字差別並不大。By the way,題目問的是「所有漢字」疊加,現在 Unicode 裡面的所謂漢字已經積累到了 92856 個[1],考慮到手邊機器的算力以及實際字體的支持情況,這裡只拿 GB2312 裡面的 6763 個漢字來玩。
圖中的藍色邊框大致就是字身框,而字面框並不是字體文件本身帶有的數據,只能通過後期分析(或者私底下問設計師)【實際上 OpenType 規範中允許在BASE表中寫入字面框信息(icft和icfb基線標籤)[2],但大多數國內廠商的字體中並沒有提供BASE表,思源和很多日本字體則是有的。感謝 Celestial Phineas!】。上面挑了四種字體,兩宋兩黑。大致可以看出,字面框的大小從上往下遞增,這也符合我們日常的感覺:中易宋體字面最小,結構緊湊;微軟雅黑字面最大,結構寬鬆,但密排時感覺過於擁擠、喘不過氣而來;思源宋體、黑體介於其間,觀感現代而又不顯慵懶(好能扯)。
BASE
icft
icfb
另一方面,除了分析字面率,疊加實驗還可以幫助我們理解筆畫的分布。上面的圖其實並不是一片均勻的黑色,而是有濃淡分布的。顯然,黑色較深的地方就對應著筆畫的集中分布。我們看那兩個宋體,都是左側有明顯的一豎,右側下面有一橫,而且右下角有一處格外明顯的黑色區域;右側還有一些不太明顯的橫豎筆畫分布。這就可以得出以下結論:
而對於字體設計師,還可以考慮下面這些問題:
這些問題歡迎大家(尤其是設計師朋友們)思考一下。
上面實驗的都是宋體和黑體,我們可以再來試一下其他風格:
這裡只用 400 字疊加,差不多也夠了。從上到下,書寫的感覺越來越強烈,體現在字面率越來越小,重疊的筆畫越來越少,曲線的感覺越來越明顯。但無論是哪種字體,我們都可以看出十分明顯的左右結構——畢竟這是漢字本身的特點。
還有一些別的東西可以玩,比如疊加獨體、左右結構、上下結構、包圍結構的漢字:
我似乎已經看到了 biang 字 2333。
漢字還有相當數量的衍生文字,在中國少數民族地區和泛東亞文化圈都被廣泛使用。包括日文平假名、片假名(評論區:假名像個球 2333):
諺文音節:
相比漢字,留下的空白就要多很多了。
應評論區要求補上注音符號:
以及女書、契丹小字和西夏文:
這些文字保留了漢字的一些特徵,但又有所不同。比如女書整體造型呈菱形,完全不同於漢字的方塊造型[4]。西夏文和漢字類似,存在大量肉眼可見的左右結構字,但和漢字相比,左右部分大小基本相同,結構更加對稱(不過 Noto 這個西夏文字體被噴得很慘[5])。
最後, @韓泳思 提到了點陣字體的問題,我們也來欣賞一下:
Unifont 中的漢字基本是 16×15 像素,為了防止密排時連在一起留了一個像素,但仍然有不少字會落到最右側的一列中。不過圖中可以看到,右上角還有最後一個空白沒有被佔領,所以我們可以得出結論:即使是點陣字體,所有漢字全部疊加起來也還是會留下空白(只考慮 Unicode 統一表意文字的範圍)。
實驗用的是 XeTeX,並用pdftopng導出圖片。附上代碼:
pdftopng
documentclass{standalone} usepackage{tikz,xeCJK}
% 字體 setCJKmainfont{Source Han Serif SC}
% 透明度、顏色 defOption{opacity=0.1, color=black}
egin{document}
fontsize{200}{200} selectfont
ExplSyntaxOn
% 漢字列表 clist_set:Nn c_han_gb_clist { 一丁七萬丈三上下丌不, 與丐丑專且丕世丘丙業, 今國意我永然警轉酬隨風鷹, 一乍丘中乎主串互予乃亂丫丐且丈三雲上丹了並乘乩乏丁世乖久井不丕乾乞五乙丸之事丞於下七乳二也丑九丟么丙, 交仁丐且仲仔丟之乙些主伏什丸予九介丹亮亨事仞也仿任井伐伯付伍上仆伉亙份乞亟企仍丑丕仟亦五以丘仗仄並雲仰一丫久他乘享了下不中乖世乏七仕么乳丞互串亂乎亭京件仇丈今仃伕於丁乍二休亥亡仙丙人伊亞代三令乩乃仳乾, }
clist_map_inline:Nn c_han_gb_clist { egin{tikzpicture}[every node/.style={inner sep=0,outer sep=0}]
ode [color=blue!60!black] at (0,0) { makebox [0pt] { dim_set:Nn fboxsep {0pt} dim_set:Nn fboxrule {2pt} fbox { color {white}
ule {1em} {1em} } } }; exp_args:NNo ode [Option] at (0,0) { kern50pt l_map_inline:nn {#1} { makebox [0pt] {##1} } kern50pt };
ode at (0,-4.2) { tfamily huge l_count:n {#1} }; end{tikzpicture} }
ExplSyntaxOff
end{document}
用Windows自帶的中易宋體,用JS將Unicode的CJK基本區的所有漢字疊起來是這樣的。代碼相當簡單,放後頭了。反正中間是填滿了,但是邊邊角角還是乾乾巴巴、麻麻賴賴的。
&& &
@韓泳思 說點陣字會,但拿中易宋體的點陣來說,其實還是沒完全填滿的。
@蒼原雪 用目前市面上最細的字體漢儀旗黑25S的話是這個效果(白邊部分是只出現過幾次的情況)。同樣一點兒空當也沒有。
五更了,這一次應評論區小夥伴要求,畫漢字的熱力圖。 @諸葛不亮 @夕雪 @polarlion。這回不再隨機選,而是依次畫Unicode列表裡漢字的前「1,10,100,1k,10k,20k」疊加的熱力圖效果。很有意思的是前1000個漢字情形能明顯的看出左右結構,存在大量單人旁的字。一直到畫完所有的2萬字左右依然可隱約看出左右結構。@王贇 Maigo
四更下,有小夥伴 @興趣寶貝 提出將漢字諺文與平假名片假名橫向比較有失公允。下面直接比較下漢字偏旁部首,平假名/片假名,韓語字母。三者總數量很接近,隨機取相同數目展示如下:
再更下,多謝 @王贇 Maigo 指正,韓語Unicode只到D7A3,共計11172字「少了11個」。
多謝 @王贇 Maigo @Wayne 提出日語字體的問題。最後面補上不同日語字體的比較。
「二更」受高贊回答啟發,一併把日語和韓語的動圖也畫了。日語當然僅僅是平假名和片假名。最終看起來漢字的確是方塊字。韓語排列組合拼湊的痕迹太明顯,疊加字數不太多的時候具有明顯的上下結構。日語平假名和片假名合起來像個球。哈哈。
雖然不懂語言學,但是用matplotlib簡單的畫了下,效果如下:
漢字疊加效果
畫圖的時候刻意給漢字設置了5%的透明度,當總數到200基本就是一團黑了。但是一直畫到2萬字依然感覺黑色區域總面積還在增加。
韓語疊加效果
日語平假名/片假名疊加效果
或許是因為平假名/片假名一共只有90幾個字元,或許是其採用了草書效果,真的看起來像個球。
橫向比較下,中日韓三語各隨機取90個字元「日語可取的太少了」如下:
補充下不同日語字體的比較,這些字體是Mac上matplotlib自帶的。畫圖的時候採用了相同的字體大小,那個像個球的中易黑體明顯比其他小很多。
matplotlib畫圖使用的是Unicode:
代碼如下:
import random def chinese(num): 隨機選取num個中文字元 chineselist = [chr(i) for i in range(0x4E00,0x9FD5+1)] return random.sample(chineselist, num)
def japanese(num): 隨機選取num個日文總平假名/片假名數字元 japaneselist = [chr(i) for i in range(0x3041, 0x309f+1) if not (i == 0x3097 or i == 0x3098 )] + [chr(i) for i in range(0x30a0, 0x30ff+1)] return random.sample(japaneselist, num)
def korean(num): 隨機選取num個韓文字元 koreanlist = [chr(i) for i in range(0xAC00, 0xD7AF+1)] return random.sample(koreanlist, num)
示例圖:
import matplotlib.pyplot as plt import matplotlib.patches as patches from matplotlib import font_manager fontP = font_manager.FontProperties() fontP.set_family(SimHei) fontP.set_size(200) fontP1 = font_manager.FontProperties() fontP1.set_family(SimHei) fontP3 = font_manager.FontProperties() fontP3.set_family(AppleGothic) fontP3.set_size(200)
fig, axs = plt.subplots(1,3, figsize = (12,4), dpi = 100) plt.subplots_adjust(wspace = 0.1) num = 90
labels = [漢字,日語, 韓語]
for i in range(len(axs)): axs[i].axis(off) rect = patches.Rectangle((0.05,0.05),0.9,0.9,linewidth_=1,edgecolor=r,facecolor=none) axs[i].add_patch(rect) axs[i].set_title(labels[i], fontproperties=fontP1, fontsize = 20 )
for t in chinese(num): axs[0].text(0.03,0.16, r%s%(t), fontproperties=fontP, transform = axs[0].transAxes, alpha = 0.05) for t in japanese(num): axs[1].text(0.03,0.16, r%s%(t), fontproperties=fontP, transform = axs[1].transAxes, alpha = 0.05) for t in korean(num): axs[2].text(0.03,0.16, r%s%(t), fontproperties=fontP3, transform = axs[2].transAxes, alpha = 0.05)
plt.savefig(cjk.png, dpi = 300, bbox_inches = tight)
紙上得來終覺淺,絕知此事要宮刑!
背景畫布:1500x1500;
字體: 思源宋體-超細(專門用了超細減輕筆劃遮蓋);
大小:1100;
字數: 20901個,全中文;
200個漢字和20000個漢字疊加的效果差不多
效果如下:
實際上:
20個就這樣了:
50個就這樣了:
100個就這樣了:
我也來個python代碼:
from PIL import Image, ImageDraw,ImageFont
str_hineses=[] start,end = (0x4E00, 0x9FD5) #漢字編碼的範圍,20950個漢字
for codepoint in range(int(start),int(end)+1): str_hineses.append(chr(codepoint))
img = Image.new(RGB, (1024, 1024), (255, 255, 255)) draw = ImageDraw.Draw(img) font = ImageFont.truetype(simsun.ttc, 1024)
for str_hinese in str_hineses: draw.text((0, 0), str_hinese, fill=(255, 0, 0), font=font)
img.show()