Skip to content

Commit 54f4332

Browse files
committed
【新增】双优化模式支持
1 parent b11c7a9 commit 54f4332

12 files changed

Lines changed: 427 additions & 164 deletions

README.en.md

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ This font also optimizes the mapping of commonly used graphic symbols in termina
5353
Here, `` is mapped to the letter `r`, `` to `T`, `` to `J`, etc.
5454
Such mappings maximize display improvement while minimizing the use of additional glyphs (:-D).
5555

56-
![font-cengluan performance in btop](assets/btop.png)
57-
5856
### Character Width Display Optimization
5957

6058
In conventional text display scenarios:
@@ -69,19 +67,31 @@ However, PC Screen Font 2 (PSF2) is a fixed-width bitmap font format that does n
6967
- If all characters are displayed with a width of one unit: full-width characters only show the left half, with the right half displayed as the [32nd character](#the-32nd-character);
7068
- If all characters are displayed with a width of two units: all half-width characters occupy two columns, but visually they are only one unit wide, resulting in [large gaps between two half-width characters](assets/display_old_old.png).
7169

72-
Given the high difficulty of finding or designing "tall and narrow half-width monospaced Chinese fonts" or "adapted full-width English letter fonts", the old solution of font-cengluan mapped all English letters, Arabic numerals, ASCII punctuation, etc., to full-width characters in the UTF-8 high range; the result was [still excessive spacing between half-width characters](assets/display_old.png).
70+
Given the high difficulty of finding or designing "tall, thin half-width monospaced Chinese character fonts" or "compatible full-width English letter fonts", font-cengluan adopts two design approaches:
71+
72+
1. Map all English letters, Arabic numerals, ASCII punctuation, and similar characters to full-width characters in the UTF-8 high range;
73+
the spacing between half-width characters remains slightly large.
74+
75+
![Full-width font-cengluan performance in btop](assets/btop_old.png)
7376

74-
In the current solution, all half-width characters are scaled by an integer factor of two, while full-width characters are displayed at the original scaling ratio with complementary blank rows above and below.
77+
2. Display all half-width characters with integer scaling doubled, while full-width characters are displayed at their original scaling ratio with padded blank lines above and below.
7578

76-
![Half-width characters extended, full-width characters complemented](assets/Half-width_characters_extended__full-width_characters_complemented.svg)
79+
![Half-width scaling, full-width complement](assets/Half-width_characters_extended__full-width_characters_complemented.svg)
80+
![Half-width scaling, full-width complement font-cengluan performance in btop](assets/btop.png)
7781

7882
Although each full-width character is still separated on the right by a [32nd character](#the-32nd-character), font-cengluan achieves a relatively balanced visual appearance overall.
7983

8084
### The 32nd Character
8185

8286
In Linux TTY, the 32nd character of the default font is `U+20`, i.e., a space. This character is used to fill positions in the background where no character is present.
8387

84-
## Building the Font
88+
## Get the Font
89+
90+
### Downloading the Font
91+
92+
- [Download the font](https://github.com/PJ-568/font-cengluan/releases/latest)
93+
94+
### Building the Font
8595

8696
1. Clone the repository:
8797

README.md

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@ cengluan 是一个为 Linux 设计的中文 TTY 字体,旨在在不安装诸
5656
其中,`` 被映射为字母 `r``` 被映射为字母 `T``` 被映射为字母 `J` 等。
5757
此类映射在尽量不占用更多字形的情况下最大程度地改善了显示效果(:-D)。
5858

59-
![font-cengluan 在 btop 下的表现](assets/btop.png)
60-
6159
### 字宽显示优化
6260

6361
在常规情景的文本显示中:
@@ -73,21 +71,31 @@ cengluan 是一个为 Linux 设计的中文 TTY 字体,旨在在不安装诸
7371
- 所有字符以宽一个单位显示:全角字符仅显示左半截,右半截显示为字体中的[第三十二个字符](#第三十二个字符)
7472
- 所有字符以宽二个单位显示:所有半角字符占满两行,但视觉宽仅一单位,导致[两个半角字符间有大空隙](assets/display_old_old.png)
7573

76-
鉴于寻找和设计“瘦高半角等宽汉字等字体”或“适配的全角英文字母等字体”的高难度。
77-
旧方案下 font-cengluan 将所有英文字母、阿拉伯数字、ASCII 标点符号等字映射为 UTF-8 高位的全角字符;
78-
结果[半角字符之间的间隔仍过大](assets/display_old.png)
74+
鉴于寻找和设计“瘦高半角等宽汉字等字体”或“适配的全角英文字母等字体”的高难度,font-cengluan 采取两种设计方案:
75+
76+
1. 将所有英文字母、阿拉伯数字、ASCII 标点符号等字映射为 UTF-8 高位的全角字符;
77+
结果半角字符之间的间隔仍略大。
78+
79+
![全全角 font-cengluan 在 btop 下的表现](assets/btop_old.png)
7980

80-
当前方案下,将所有半角字符整数缩放二倍显示,全角字符在补全上下空行的情况下以原缩放比例显示。
81+
2. 将所有半角字符整数缩放二倍显示,全角字符在补全上下空行的情况下以原缩放比例显示。
8182

82-
![半角放大、全角补全](assets/Half-width_characters_extended__full-width_characters_complemented.svg)
83+
![半角放大、全角补全](assets/Half-width_characters_extended__full-width_characters_complemented.svg)
84+
![半角放大、全角补全 font-cengluan 在 btop 下的表现](assets/btop.png)
8385

8486
虽每个全角字符右侧仍被一个[第三十二个字符](#第三十二个字符)隔开,font-cengluan 在总体视觉上达到相对平衡。
8587

8688
### 第三十二个字符
8789

8890
Linux TTY 默认第字体的三十二个字符为 `U+20`,既空格。这个位置的字符被用来填充背景中没有字符的位置。
8991

90-
## 构建字体
92+
## 获取字体
93+
94+
### 下载
95+
96+
- [下载最新版本](https://github.com/PJ-568/font-cengluan/releases/latest)
97+
98+
### 构建
9199

92100
1. 克隆仓库:
93101

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
3.0.0
1+
3.1.0

assets/btop_old.png

691 KB
Loading

assets/display.png

-31.9 KB
Loading

assets/display_new.png

125 KB
Loading

assets/display_old.png

-93 KB
Binary file not shown.

build.bash

Lines changed: 57 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,58 @@
11
#!/bin/bash
22

33
path=$(pwd)
4-
brand="cengluan"
4+
5+
# 品牌名称,可通过第一个参数覆盖
6+
if [ $# -ge 1 ]; then
7+
case "$1" in
8+
-h|--help)
9+
echo "用法: $0 [品牌名称]"
10+
echo "生成指定品牌的字体文件。"
11+
echo "如果不提供参数,默认使用 'cengluan'。"
12+
exit 0
13+
;;
14+
*)
15+
brand="$1"
16+
;;
17+
esac
18+
else
19+
brand="cengluan"
20+
fi
521

622
# 创建必要的目录
723
mkdir -p $path/temp
824
mkdir -p $path/output
925

10-
# 下载 fusion-pixel-12px-monospaced-zh_hans 的压缩包
11-
download_url="https://github.com/TakWolf/fusion-pixel-font/releases/download/2026.01.04/fusion-pixel-font-12px-monospaced-bdf-v2026.01.04.zip"
12-
wget "$download_url" -O $path/temp/font.zip
26+
# 检查字体包是否已经存在
27+
if [ ! -f "$path/temp/fusion-pixel-12px-monospaced-zh_hans.bdf" ]; then
28+
# 下载 fusion-pixel-12px-monospaced-zh_hans 的压缩包
29+
download_url="https://github.com/TakWolf/fusion-pixel-font/releases/download/2026.01.04/fusion-pixel-font-12px-monospaced-bdf-v2026.01.04.zip"
30+
wget "$download_url" -O $path/temp/font.zip
1331

14-
# 检查下载是否成功
15-
if [ $? -ne 0 ]; then
16-
echo "错误: 下载文件失败。"
17-
exit 1
18-
fi
32+
# 检查下载是否成功
33+
if [ $? -ne 0 ]; then
34+
echo "错误: 下载文件失败。"
35+
exit 1
36+
fi
1937

20-
# 解压下载的压缩包到 $path/temp
21-
unzip $path/temp/font.zip -d $path/temp
38+
# 解压下载的压缩包到 $path/temp
39+
unzip $path/temp/font.zip -d $path/temp
2240

23-
# 检查解压是否成功
24-
if [ $? -ne 0 ]; then
25-
echo "错误: 解压文件失败。"
26-
exit 1
27-
fi
41+
# 检查解压是否成功
42+
if [ $? -ne 0 ]; then
43+
echo "错误: 解压文件失败。"
44+
exit 1
45+
fi
2846

29-
# 列出解压后的目录内容
30-
ls $path/temp/
47+
# 列出解压后的目录内容
48+
ls $path/temp/
49+
else
50+
echo "字体包已存在,跳过下载和解压。"
51+
fi
3152

3253
# 运行 Python 脚本
3354
python3 $path/build_font_from_bdf.py "$path/temp/fusion-pixel-12px-monospaced-zh_hans.bdf" > $path/output/$brand.txt
55+
python3 $path/build_font_from_bdf_new.py "$path/temp/fusion-pixel-12px-monospaced-zh_hans.bdf" > $path/output/$brand-new.txt
3456
# python3 $path/build_font_from_bdf.py "$path/temp/fusion-pixel-12px-monospaced-zh_hant.bdf" > $path/output/$brand-zh_hant.txt
3557

3658
# 检查脚本执行是否成功
@@ -39,22 +61,26 @@ if [ $? -ne 0 ]; then
3961
exit 1
4062
fi
4163

42-
# 下载并编译 psftools
43-
wget https://www.seasip.info/Unix/PSF/psftools-1.0.14.tar.gz -O $path/temp/psftools-1.0.14.tar.gz
44-
tar -xf $path/temp/psftools-1.0.14.tar.gz -C $path/temp/
45-
cd $path/temp/psftools-1.0.14
46-
./configure
47-
make
48-
cd $path/
49-
50-
# 检查压缩是否成功
51-
if [ $? -ne 0 ]; then
52-
echo "错误: 下载并编译 psftools失败。"
53-
exit 1
64+
# 检查 psftools 是否已经编译
65+
if [ ! -f "$path/temp/psftools-1.0.14/tools/txt2psf" ]; then
66+
# 下载并编译 psftools
67+
wget https://www.seasip.info/Unix/PSF/psftools-1.0.14.tar.gz -O $path/temp/psftools-1.0.14.tar.gz
68+
tar -xf $path/temp/psftools-1.0.14.tar.gz -C $path/temp/
69+
cd $path/temp/psftools-1.0.14 && \
70+
./configure && \
71+
make
72+
if [ $? -ne 0 ]; then
73+
echo "错误: 下载并编译 psftools失败。"
74+
exit 1
75+
fi
76+
cd $path/
77+
else
78+
echo "psftools 已编译,跳过下载和编译。"
5479
fi
5580

5681
# 将 txt 文件转换为 psf 文件
5782
$path/temp/psftools-1.0.14/tools/txt2psf $path/output/$brand.txt $path/output/$brand.psf
83+
$path/temp/psftools-1.0.14/tools/txt2psf $path/output/$brand-new.txt $path/output/$brand-new.psf
5884
# $path/temp/psftools-1.0.14/tools/txt2psf $path/output/$brand-zh_hant.txt $path/output/$brand-zh_hant.psf
5985

6086
# 检查转换是否成功
@@ -65,6 +91,7 @@ fi
6591

6692
# 压缩 psf 文件
6793
gzip -c $path/output/$brand.psf > $path/output/$brand.psfu.gz
94+
gzip -c $path/output/$brand-new.psf > $path/output/$brand-new.psfu.gz
6895
# gzip -c $path/output/$brand-zh_hant.psf > $path/output/$brand-zh_hant.psfu.gz
6996

7097
# 检查压缩是否成功

build_font_from_bdf.py

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
Flags: 1
3636
Length: 512
3737
Width: {width}
38-
Height: {height * 2}''', end='')
38+
Height: {height}''', end='')
3939

4040
def PrintNonChineseCharacter(index):
4141
count = index
@@ -51,7 +51,7 @@ def PrintNonChineseCharacter(index):
5151
count += 1
5252
return count
5353

54-
def PrintCharacters(Characters, count, is_fullwidth_cha = False):
54+
def PrintCharacters(Characters, count):
5555
Character = Characters[0] # 取第一个字符作为展示字
5656
try:
5757
# 将字符编码为对应编码
@@ -83,27 +83,11 @@ def PrintCharacters(Characters, count, is_fullwidth_cha = False):
8383
pixels[-bottom - h + i + v_offset][left + j] = ("#" if o_pixels[i][j] else "-")
8484

8585
# 打印像素矩阵
86-
if is_fullwidth_cha: # 全角字符:一倍打印,上下补全
87-
blank_row = "".join("-" for i in range(width))
88-
for i in range(height // 2):
89-
print(blank_row + " \\")
90-
for row_h in range(top_gap, height + 1 - bottom_gap):
91-
row = "".join(pixels[row_h])
92-
print(row + " \\")
93-
for i in range(height // 2 - 1):
94-
print(blank_row + " \\")
95-
print(blank_row)
96-
else: # 半角字符:去掉右半边,把左半边缩放两倍打印
97-
for row_h in range(top_gap, height + 1 - bottom_gap):
98-
row = "".join(pixels[row_h])
99-
row = row[:len(row)//2] # 去掉右半边
100-
row = "".join(c * 2 for c in row) # 左右缩放两倍
101-
if row_h < height:
102-
print(row + " \\")
103-
print(row + " \\")
104-
else:
105-
print(row + " \\")
106-
print(row)
86+
for l in range(top_gap, height + 1 - bottom_gap):
87+
ll = "".join(pixels[l])
88+
if l < height :
89+
ll = ll + " \\"
90+
print(ll)
10791

10892
# 打印字符的 Unicode 编码
10993
print("Unicode: ", end="")
@@ -129,5 +113,5 @@ def PrintCharacters(Characters, count, is_fullwidth_cha = False):
129113
s = line.split() # 分开拼音和汉字
130114
if len(s) >= 2:
131115
hanzis = s[1] # 取汉字那一条
132-
PrintCharacters(hanzis, count, True)
133-
count += 1
116+
PrintCharacters(hanzis, count)
117+
count += 1

0 commit comments

Comments
 (0)