TakWolf / ark-pixel-font

Open source Pan-CJK pixel font / 开源的泛中日韩像素字体

Home Page:http://ark-pixel-font.takwolf.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

字体对齐偏下了一点点

seabye opened this issue · comments

commented
Screenshot 2023-11-07 16 39 50 苹方

--

Screenshot 2023-11-07 16 40 10 ark pixel / fusion-pixel 12px(截图是后者,但前者有相同问题)

--

Screenshot 2023-11-07 16 40 23 vonwaon bitmap 12px(另一像素,但它是偏上了一点点)

====

这个事情是严重的,望测试。截图是我使用在web中(woff2),在2x缩放的macos中的显示(chrome与safari相同结果)。界面元素经常有边距不小的框体,一方面是这导致框体的上下边距始终细微的偏移,另一方面是,当该字体与比如字体图标组合时,产生的一个正常,一个偏移。

Screenshot 2023-11-07 16 46 50 与苹方

--

Screenshot 2023-11-07 16 46 14 与ark pixel / fusion-pixel 12px(截图是后者,但前者有相同问题)

此处的字体图标也是苹果家的SF Pro,不过这点并不是因为苹果家两套自己对齐自己,其它字体图标也是要一直垂直位置居中的。

← ← 这是致命的,但一纠正好就完美了。正常其它哪怕系统自带的字体也不少有对齐不一致难以调整的情况,但大致而言还是存在一个:到底是否居中了没有的值的。(我在macos中测试苹果(PingFang SC)、微软(Microsoft YaHei / Microsoft YaHei UI)、谷歌(Noto Sans CJK SC)的自带默认字体都是没有偏移问题的)。

请务必修正!

====

补充一点,这个必须要同时使用多个字体时才显现问题。在一些程序中可能只能指定单个字体,它不会有这个问题,只要单独对它进行整个调整即可。但比如web中存在这个问题是这样发生的:先被指定的字体会成为垂直居中的依据,比如以ark pixel为首选字体时,所有其它字体的文字或字体图标如果并列一起的话,会跟随ark pixel的垂直位置,这就导致:当ark pixel偏下时 且ark pixel为首选时,其它字体就会呈现为往上飘,此时ark pixel是居中的,但其它字体不居中了,往上走了。而如果以其它字体为首选,接着是ark pixel,则ark pixel会呈现偏下。

就是这个问题,我认为的方案是与大部分操作系统的文字的线对齐,比如macos的。

可能的原因是,ark-pixel/fusion-pixel 12px 字形实际是 11x11,顶部和右侧自带1像素边距,例如:

image

顶部和右侧的1px边距空白是算在字宽和行高中的,而字体默认行间距和字间距为 0。

目前是故意这样设计,因为大部分像素字体的使用场景,都会优先考虑精确的像素尺寸计算,不能让上下左右各为 0.5 像素(在矢量渲染中其实没问题,但是如果在精确像素栅格化的场景,就会无法对其)。

commented

@TakWolf 现在三个字号 哪些是有这种情况的。以我个人的使用来说,如果是这个问题导致偏移。那么我会使用11px的没有偏移的(哪怕在web 我将其指定显示为12px 此时也没有偏移),而如果使用这个12px,按照前面我的情况,它几乎没法用,如果有不偏移的,肯定找不偏移的。(那么 是提供11px字号的字体文件 : D,也许就没事了)

← ← 我需要不偏移的。因为有其它字体,以及字体图标这种不可能不并列存在。

commented

现在chrome已经取消了最小字号是12px的限制(过去中文区域是用户的默认设置最小12px),人类的一大步。在,比如高清屏具备2x缩放的情况,实际上,将11px 12px,显示为其它像素大小,不完全对称也不会显现某种可能的 非点对点 的问题。而对齐这个问题,就直接导致不可用。想象一下我们现在所在的github界面,上面的小图标和文字每处都存在这种情况,是难以使用的。

所有字号都有偏移。
8px --> 7x7 + 1px border
10px --> 9x9 + 1px border
12px --> 11x11 + 1px border

commented

那,可以裁掉多余的1px,给出7px、9px、11px版本么。可能像素game领域没有问题。但至少非game的gui领域web部分,这样没法用,因为界面就像github这些界面的条框一样非常复杂,当字体存在偏移就只有一个结果,要不让这个字体偏下,要不让其它字体和图标全偏上,都是不可用状态。方便的话给出去除多余像素的,不方便的话,你决策一下这个事情到底需不需要先,我现在怎么调都不可能让自己的界面正常(如果web提供针对不同字体的行高线的css调整接口,那么这个问题可以解决,但是没有这种接口。css中对文字最高级的部分只到,允许选择加载的字体是哪个区段,但无法调整这些)。如果我想使用上像素字体,我现在在尝试找找有没有无偏移的字体。

这个问题实际上相当复杂。以 12px 为例:

字形尺寸为 11 x 11 单数,这样可以保证有中心轴像素,让上下 或 左右保持对其。例如汉字“中”就可以很好绘制,否则处理起来很麻烦。

字和字之间必须有边距(1px)来保证视觉上的独立,这个边距必须要包含在字形中(advance_width 和 line_height)来保证连字符能够正常显示,例如制表符、破折号和其他特殊字符。一般矢量字体都是上下左右给相同的空白边距。但是像素字体不行,不能设置为 0.5px。因为如果按照 12px 尺寸来进行栅格化,就会发现像素是对不齐的,会出发插值算法造成模糊,因此只能保持正数边距。

无边距字体有这个:https://github.com/TakWolf-Deprecated/hzk-pixel-font
和 vonwaon 使用相同的字形源。上下左右均无自带边距,这个理论上可以上下居中

image

这个是宋体风格而不是黑体风格,因为存在装饰,所以边距效应不明显

补充一点,这个必须要同时使用多个字体时才显现问题。在一些程序中可能只能指定单个字体,它不会有这个问题,只要单独对它进行整个调整即可。但比如web中存在这个问题是这样发生的:先被指定的字体会成为垂直居中的依据,比如以ark pixel为首选字体时,所有其它字体的文字或字体图标如果并列一起的话,会跟随ark pixel的垂直位置,这就导致:当ark pixel偏下时 且ark pixel为首选时,其它字体就会呈现为往上飘,此时ark pixel是居中的,但其它字体不居中了,往上走了。而如果以其它字体为首选,接着是ark pixel,则ark pixel会呈现偏下。

就是这个问题,我认为的方案是与大部分操作系统的文字的线对齐,比如macos的。

这是另外一个问题。多字体情况下,通常的排版布局,文字是按照 基线对齐的 (baseline)。你尝试使用比例模式(proportional) 版本试一下

比例模式的基线在这里(红线位置),如果他和其他字体进行 fallback,那么红线会和其他字体的基线对齐

image

commented

理解。如果在左侧和下方也增加一格,能否解决过于贴靠一起的问题,同时也没有不居中问题。这会使字号变成9px 11px 13px。但不试试不知道这个效果会怎么样。

--

还有一个事情会导致我仍然会坚持,应该提供无边距的字体。原因是比如上面的例子(hzk-pixel-font),编程可以设定行间距,其实也可以设定字间距,也就是说,上下左右的间距都是代码可控的,可以不由字体来制造(而这个方式却又带有导致巨大问题存在)。

Screenshot 2023-11-07 18 15 49

--

Screenshot 2023-11-07 18 16 07

--

你可以打开控制台选中文本区域的div,往css临时加入它:letter-spacing: 2px;

这在web是一个css属性,以上我增加了2px字间距离(在native,以及游戏开发中,我不清楚是否操作系统与游戏引擎提供的接口是否便利这么做)。也就是说,对于我遇到的问题,letter-spacing: 2px; 加上上下左右都居中但无边距的字体可以解决居中问题,但是仍然会带来另一个问题,即这样一来,全局所有字体的间距都会有2px(主要我们考虑并列问题),但当有这种接口时,它比无法纠正的单边距要好。

综合。字间距可能是编程能解决的,可以不用字体自带这个边距。以及 如果让字体自带相等的边距会如何(增加缺少的一边,而不是0.5px)。

==

如果我们能确定在多数编程场合,编程手段控制字间距不是问题,那么应该是提供无边距的会更好。自带对等边距可能也可以(因为无法确定字体使用者是谁,并不一定都是编程人员,比如看小说或者替换系统字体,此时字间距不由使用者可代码决定),不过这样字号就不是现在的数字了。

==

前面的缩放了(我在两倍缩放的屏幕缩放页面为50%,那么设定的2px实际显示是1px效果差不多),emmm,补充个4px。

Screenshot 2023-11-07 18 30 16
commented

我尝试了proportional版。以下是情况,基本符合你的描述。

  • 如果以其它字体为首选,proportional版会将自身对齐到首选字体,此时都不偏移(但右侧的多余1像素仍然存在)。坏消息是:chrome与firefox支持这么做,但safari的情况有些复杂(如果存在两种字体混搭在一个div里,那么会和chrome一样正确的对齐即按照首选字体。而如果一个div里只有非首选字体 不知道为什么它会选择非首选字体产生向下偏移——这点是反常情况。。。)
  • 如果是以proportional版为首选,则所有内容一起向下偏移。

存在一些浏览器实现的问题。以及右侧1px不能依赖这个解决。

commented

还有个事情是,为了能使以这种方式对齐垂直部分的话(即便不考虑此处safari还无法正常显示),那么首选字体就一定不能是pixel。于是,字母和数字一定会被首选字体拿走,无法显示为pixel。(因为要先用一个对齐正确的英文字体当首选)

== 补充

好像这么说也不完全正确,前面我描述过对于web css可以选择字体区段,我应该可以让首选字体的区段为某个非字母数字。嗯,这样就只剩下浏览器bug,和右侧1px。

commented

← ← 感觉没法这样解决的。本身往字体增加不对称间距引发的问题,解决方式也会有很多衍生问题。我不是很明白为什么不能是9px 11px 13px(不是很了解字体制作,我只调整过字体图标的制作,知道有那些线条,但意义不是很明了)。一般来说,不管是游戏还是什么,应该不限制一定要用偶数字号,如果是这样的话,且增加对称1px距离也是美观的话,我觉得:由编程控制的无距离,或自带对称距离但改变字号,都会比先以错位的字体方式带来某种间距要好,因为后面衍生的问题几乎不能解决(前提是我想当然的认为,要对称就是往左侧和下方增加1px 然后字号增加1px 事情是这么回事)。

commented

我尝试了hzk-pixel。它没有自带边距问题,但无法与字体图标混搭。应该是哪里还是没对。当单独只有文字且是首选时是正确的。混搭字体图标时,无论是否放首选都不成立。

= = 暂时放弃了!

这个问题实际很复杂,涉及到很多问题。

还有一个事情会导致我仍然会坚持,应该提供无边距的字体。原因是比如上面的例子(hzk-pixel-font),编程可以设定行间距,其实也可以设定字间距,也就是说,上下左右的间距都是代码可控的,可以不由字体来制造(而这个方式却又带有导致巨大问题存在)。

自定义字间距和行间距不能解决问题。查看:https://ark-pixel-font.takwolf.com/alphabet-12px-monospaced.html

image

这部分的字形是 方块元素 u2580-u259F制表符2500—257F

这类字符是可以紧凑排列的,而汉字则需要间距。字体必须在同一套默认参数下兼容这两种情况。因此通常字体的默认行间距和字间距才设定为0,而要求字符自行提供字间距。

我不是很明白为什么不能是9px 11px 13px(不是很了解字体制作,我只调整过字体图标的制作,知道有那些线条,但意义不是很明了)。一般来说,不管是游戏还是什么,应该不限制一定要用偶数字号,

字体字号实际上无所谓。一般常规矢量字体实际上是没有字号这种东西的。像素字体现在有这个字号是因为实际使用时,要进行栅格化,必须要保证像素对其。12px 实际的含义是,你只有将渲染尺寸设置为 12 或者整数倍的时候,才能清晰不模糊的进行栅格化渲染。你在一个高清屏上(x2 gui)上就按照 60px 渲染,也是可以的,边缘模糊也不明显,也可以用。但是在像素环境下不行,必须要让像素能够明确的对其,12px 的字体就不能渲染为 13px,这样就对不齐,就会模糊。

当然,也没有要求必须要偶数。只不过在实践中发现,11x11 + 1 border 正好可以满足字形居中对称,并且字号为偶数。方正像素字体的字形是 11x12,右侧有边距但是顶部没有,他没有上下居中问题。这只是设计根据喜好师采用的方案。方舟用了这套参数方案。

另外,多个字体通用混排导致的不对齐是另外一个问题。这上面边距的问题无关。

多个字体通常是按照 baseline 来对其的。baseline 就是大写西文字母下边那条线。红线位置。

WechatIMG15aa16

这是西文字母才有的概念。汉字并没有基线这个概念。但是通常字体为了兼容西文字母,都会设置基线。上图中是 chrome 默认字体,你回发现基线不在汉字底部,而在上面一点。汉字高度整体也比西文字母大一圈。

方舟12px 比例模式 基线位置是符合一般字体比例的,当然必须要求在正数位置(保证精确栅格化)。现在在汉字 -1 位置。
WechatIadsfasfadsfasdMG1517

现在方舟的基线这个位置对方舟来说是合理的,但没法保证你跟其他字体组合的时候,位置也能完全合适。多个字体混合一定会产生基线对其的问题。对西文字母来说,通常大写字母底部都坐落于基线上,但是如果包含汉字,这个问题都不一定了。需要具体来看,也没有通用的解决方案。

web 环境下的补偿方案:
https://static.takwolf.com/github/ark-pixel-font/issues/33/index.html

        .pixel-buttion2 {
            padding-left: 16px;
            padding-right: 16px;
            padding-bottom: 2px;  /* 添加内边距来修复对其问题 */
            font-family: Fusion-Pixel-12-proportional-zh_hans, sans-serif;
            font-size: 24px;
            border-color: #00adef;
            border-width: 1px;
            border-style: solid;
            border-radius: 16px;
            line-height: 40px;  /* 实际高度为 42px */
        }
commented

只是,这些本身和文字如何设计还是 不算是同一件事。更多的是技术方式上允许的可调性还不足,比如前面我提到,一旦编程接口被指作为允许单独调整某个字体的偏移之类的,那么这个问题也就也可以没有。

现在,这几款字体我都尝试了下来,唯一对齐比较好的已经是ark-pixel/fusion-pixel(除了自带的空像素,没有产生其它问题,其它字体则无论是否有多余像素,有其它导致无法对齐的问题存在。所以我很在意,如果有去掉多余像素的版本,其它素质依旧保留的情况下,它就是和苹方一样可以用在gui的像素字体)。但,它们就是自带多余像素,唯一让我无法对齐的这点。。。

是的,像素环境下不太可取,甚至是常见的电脑屏幕,尤其在windows下的非2x。你可能便好这先是像素环境下的某种适配。而我更在意的不是产生次像素,而是首先界面得能对齐,因为否则它无法用于gui制作,文字像素虽然点对点,但更具gui视觉破坏力的是对齐,而只能用于游戏(对话框,与 游戏中的很多位置不像gui流程 单独调整也不麻烦)。而对于所产生的次像素问题,从 看向未来会有更多高清屏幕(尽管从统计来看,大多数仍然是1x的1080p)以及手机已经普遍的甚至大于2x,如果字体要考虑上gui使用的话,我个人还是希望有去掉多余像素的版本。—— 但,裁掉或者增加相等边距,只是改变字号,也不会导致不点对点,只要设定的字号是对应的。

即,似乎无法单纯一套在不同用途都完美。因此,如果考虑gui制作需求的话,可能的话可以提供一下无边距或增加边距为相等的字号。

这是gui制作人员一直很难受的事情,即便常规黑体,可用的,对齐正确,组合不矛盾的,在过去就很难找到(因为这个原因,无论用户系统里自带了什么字体,都不能从程序角度允许人们随意切换,因为对齐都不一样),直到有个苹方可以拿来转成woff2。

==

队长!我们离完美只差1px了!

嘛,没事,我对web有足够的了解。各种补丁方式都可以想到,我只是想系统性的没有这个问题。增加下边距之类的要单独控制,如果切换字体是否还要把它拿掉,以及它也不能用于混搭情况,混搭必须内部子div区分混搭的两种字体内容,这会越走越长。

如此多强调只是想要让你认为,多提供无边距版本让制作gui变的简单,不需要额外修正,直接从系统字体切换到该字体,不用做其它任何代码修正。这对gui使用是很有意义的,毕竟从这么长的讨论中你也可以发现,无法用于gui,而只能用于一些游戏,或阅读目的,这样真的好吗。

但,这取决于作者的意愿。因此我强调这是否方便这么做,如果方便,且有意愿(当便利程度与意愿达成,← ← 就有了无边距/等边距版本了),直接多提供裁掉多余像素的版本是最好的方案(目前我还信息不足,没尝试过能否自己裁掉)。

如果这很麻烦,就不用考虑了。

commented
Screenshot 2023-11-07 20 13 15

这是我当前用到的场景(2x屏幕,但总体显示是13px,实际上是没有什么问题的,这种屏幕情况以及像手机,不会有过于严格的像素要求),它实际上并不会12px就仅会以12px显示,在gui并不那么强调(也强调不了,否则要每个大小都有一个特定的字体文件)点对点,也如你所说,实际上这事情是矢量的,字号对应是为了让线条看起来完美的未有边缘的柔和处理。—— 即 gui视角对齐要比是否点对点重要一些。

对每个部分单独做修正是不太科学的。去掉导致不对齐的空像素,然后字间距是可以统一的用代码增加。在这种情况下,这个字体就很完美,可以直接从苹芳/雅黑/noto切换成它。

嘛,就这样吧 ← ←,感谢讨论,补充了我不少知识。

能否提供一下目前使用的 GUI 框架,以及使用的图标字体库?方便我这里做一下技术验证

另外 ark-pixel/fusion-pixel 仓库中有完整的构建代码,可以简单通过调整代码来进行个性化定制,不太复杂

基本上只需要修改这里即可 https://github.com/TakWolf/ark-pixel-font/blob/develop/assets/glyphs/12/config.toml

此外,我觉得目前字体参数的设置与是否面向 GUI 环境没有太大关系。

如果你使用像素字体在GUI环境,那么我会假定,你至少应该使用 x2 倍数来整体缩放画布来保证像素风格。
或者你使用 x2 字体尺寸,并按照相同倍率设置你的 GUI 元素。

https://github.com/aseprite-quest/aseprite-unified-pixel-theme

image

这个给 aseprite 做的通用语言像素主题,使用 fusion-pixel-10px 比例模式(9x9 + 1)。aseprite 采用画布整体 x2 来显示,你可以看看居中是否存在违和感?

commented

是这样。通过昨天的对话我了解到,导致经常无法对齐的原因有两方面。一方面是一些基线问题,另一方面当基线之类没有问题时则来自字体自带的留白。于是我特地观察了下别的字体,非像素字体实际上也存在一些留白,但一般是上下留白基本相等,左右则右侧可能略微多一丢丢但看不出来。

ark-pixel的基线是正确的,但留白上由于存在单边情况,导致组合其它字体时一定会有问题。在你的截图中可能图标不是字体,并且不是与字体混列在一起,所以那个软件的对齐没有太大问题。而我在web的场景,现代的开发方式是:

☑ 文字
。是这样,字体图标不是作为一个div或span元素额外做对齐,而是它就是当成是文本存在直接与文字列一起的,也就是我们的bug原因。

你这样想就对了,当字体被单独使用,并不与其它字体混合的时候,是没有太大问题的,但混合的情况下是,基线没有问题,但留白导致它与旁边的其它字体文字一定是有落差的,这是肯定的,真不是bug,因为字体就确实带了不对称留白,那显示自然是高低不一致。

--

以下是昨天界面的,“苹方”字体状态、以及“猫啃什锦黑”状态,这些字体都是基线正确且留白没有明显单边问题的,可以直接切换与图标字体组合。

Screenshot 2023-11-08 11 33 03 Screenshot 2023-11-08 11 33 18

我注意到,非像素字体有不少都是没问题的。而像素字体普遍存在这个问题,并且由于视角侧重点不同,某些制作者与使用者,会视这种留白为一种优化。但这不是系统的解决方案,系统的解决方案应该是代码接口可以更好的控制像是间距,又或者我们真的不能往反方向添加相等的像素吗(这样也自带留白 但字号增大一点 这是最符合gui也能无缝切换使用的情况)。

我的界面完全没有使用任何界面框架,vanilla\原始开发的,就是普通的webview,这个没法提供(它是个重前端渲染的站点,但还没有上线,只是本地),但测试这件事很简单,混合另一个字体即可,尤其是图标字体(因为这是我们要对齐的目标。注意,图标字体有多种情况,早期的图标字体实现方式插入一个div/span或class,图标字体会往其中加入伪元素之类的,但这个做法很蠢,因为已经将图标做成woff2了为什么不是直接粘贴字符,于是后来就是这种了,图标字体会带有一个uni码,直接复制文字一样与文字排一起即可,类似我们使用emoji,emoji就是这种情况,只是它是彩色的)。

这是苹果的字体图标的一个版本粗细字号文件:

SF-Pro-Text-Regular_400.zip

在css或js加载命名该字体:

@font-face {
  font-family: "SF Pro";
  /* unicode-range: ; */
  src:
    url("./SF-Pro-Text-Regular_400.woff2") format("woff")
  ;
}

并对全局使用使用:

html {
  font-family: "仍可能要先存在一个首选字体", "SF Pro", "其它字体"; /* 正确的混合方式是分两次导入中文字体,第一次导入时设定unicode-range范围,将数字英文以及cjk标点符号包含进去,第二次是完整导入。而后使用时,先加载标点符号版命名,接着加载图标字体,最后加载完整。因为SF Pro中也包含数字英文等符号,如果不分两次,会只有SF Pro不包含的中文字体被使用。——但这件事与对齐无关。 */
}

示例符号:“􀎞􀆉􀐫􀅈”,左上角第二行前四个,这个你进图标字体复制就可以了。

然后将它与文字一起输入,正常情况是此时图标字体和普通文字字体无异,就像标点符号或各种基线设定没问题的其它字体一样可以混合。

--

我理解,该字体在某些场景可能没有问题(有时候也是界面设计问题,比如在我的界面,你看到有很多紧紧包围着图标与文字的边缘,当这种元素很多时,对齐问题就显得格外明显。而另一些设计则可能不太突出这点,则哪怕错位也看不出来或者不重要,当前元素是视整体,以及对比之下才会显现某些问题是否是问题,比如你在一个十年前的界面上,怎么错位都不会觉得有事),但在我面临的这种情况,存在这种问题,在web的字体混用,可能导致偏移的不仅是混用的div节点,而是整个的产生错综复杂的偏移。除非做一些复杂的容易造成更多难处理的html结构与css后修正工作,不能用这种思维解决这个问题,这个问题只是由于更基础的字体部分自带了偏移,字体本身不应该有单边的偏移(该字体是出于其点阵特征而这么做。我仍强调,能否在另一边补充1px,让字号+1,这个版本即是对齐的,又自带留白,它就不会产生任何问题)。它是不能以 后修复为方案的,尤其你看,当没有这种留白的字体可以直接如此简单的,切换过去而无需做任何调整,这才是自然状态。

让字体更符合标准,保持对齐是有很多长远意义的,比如哪怕游戏制作者,如果我们需要增加一些用字体做成的符号,不在ui而是对话框之类的混合使用,那么由于基础字体的偏移我们就不得不将新增的符号也做相同的偏移。接着,如果基础字体换成了其它不偏移的字体,此时新增的符号又是错位的。如果我们对偏移情况做特殊补丁,那么它仍然有问题,如果软件提供字体切换,则要这部分补丁代码也跟随一起有效和无效逻辑。这绝对是不科学的处理方法。

--

嗯。我先在物色其它非点阵的测试,找一些好的字体,有个性的同时也适于阅读的字体(像前面的“猫啃什锦黑”不太适合非标题之类的正文),而后有空再研究下能否自己处理ark-pixel/fusion-pixel的问题。点阵游戏,点阵字体是很具特色的,能的话还不想轻易完全放弃。(要做的事情实在太多了,← ←虽然是个简单的程序,但全部工作都只有一人做时,切换自己的状态……)。

另一些事。优秀的web界面并不常见,大厂的注意力都在原生客户端,web由于没有设计套件与标准交互方式,大部分界面的设计往往落后5年不止。可能要在这些地方细究的人本也不多。但就从使用这些元素的角度,程序加载图标字体,而后将图标字体如同文本字体一般的混合使用,一定是最自然简单的使用图标字体的方式。它确实不是主流,前面提及到过,早期,乃至现在你去审查github界面上的各种小图标,它是svg方式工作的而不是直接字符(这最大的好处是使用到哪些图标就加载哪些svg,而字体一般需要一次性加载整个文件,但好在图标字体体积也不大实际上不是问题——我一直也不是很明白为什么最初乃至现在主流仍然是svg而不是字体方式,明明那些开源图标字体都是有提供woff2版本的说明他们知道有这个使用方式),是呈现为<div><svg>icon<svg/><span>text</span></div>。唯一有这么做的是apple官网左下角面包屑导航的苹果图标,它是来自字体文件字符而不是svg。

--

我可能已经偏离了使用字体的目的。而是强调作为更基础元素会对之后造成的深渊影响,字体制作者与设计人员与编程人员视角的一些不同,以及各种情况也不一致,但基础元素最好还是不以取巧的方式解决自己的某些问题但可能带来更多问题。怎么说呢,它也许也不一定需要解决,有更多人在从事自己部分工作时意识到这可能有问题而多有思考这点就好了,也许会因此演进出没有该问题也符合字体设计者角度的答案。

commented

我会抽空去了解这方面,并按照你的建议看看自己能否对字体做修改工作。这些没有问题,我是个界面设计者,也是前后编程人员,大体研究研究是能解决的,毕竟边缘是统一的,只要不是让手动自己绘制每个字都可以批量解决。

此篇,也不是一定要字体方接受我的观点,而是确实有这个事情,一旦有类似的需求/使用方式,那么大部分以这种方式留白的像素字体都全军覆没没法用,这确实是个现实问题。——试图传达这件事。

https://static.takwolf.com/github/ark-pixel-font/issues/33/index.html

按钮高度为 40px 行高 + 2px 边框
文字高 24px
顶部留白 = 底部留白 = 9px

image

四个按钮均按照后备字体方式实现,分别为:

Fusion-Pixel 为主,SF-Pro 后备
SF-Pro 为主,Fusion-Pixel 后备
只用 SF-Pro
只用 Fusion-Pixel

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        @font-face {
            font-family: Fusion-Pixel-12-proportional-zh_hans;
            src: url("./fusion-pixel-12px-proportional-zh_hans.woff2");
        }
        @font-face {
            font-family: SF-Pro;
            src: url("./SF-Pro-Text-Regular_400.woff2");
        }
        .ruler-1 {
            position: fixed;
            top: 0;
            width: 100%;
            height: 42px; /* 40px 行高 + 2px 边框 */
            background-color: red;
        }
        .ruler-2 {
            position: fixed;
            top: 0;
            width: 100%;
            height: 33px;
            background-color: green;
        }
        .ruler-3 {
            position: fixed;
            top: 0;
            width: 100%;
            height: 9px;
            background-color: orange;
        }
        .gui {
            position: fixed;
            top: 0;
            width: 100%;
        }
        .font-1 {
            padding-left: 16px;
            padding-right: 16px;
            font-family: Fusion-Pixel-12-proportional-zh_hans, SF-Pro, sans-serif;
            font-size: 24px;
            border-color: #00adef;
            border-width: 1px;
            border-style: solid;
            border-radius: 16px;
            line-height: 40px;
            display: inline-block;
        }
        .font-2 {
            padding-left: 16px;
            padding-right: 16px;
            font-family: SF-Pro, Fusion-Pixel-12-proportional-zh_hans, sans-serif;
            font-size: 24px;
            border-color: #00adef;
            border-width: 1px;
            border-style: solid;
            border-radius: 16px;
            line-height: 40px;
            display: inline-block;
        }
        .font-3 {
            padding-left: 16px;
            padding-right: 16px;
            font-family: SF-Pro, sans-serif;
            font-size: 24px;
            border-color: #00adef;
            border-width: 1px;
            border-style: solid;
            border-radius: 16px;
            line-height: 40px;
            display: inline-block;
        }
        .font-4 {
            padding-left: 16px;
            padding-right: 16px;
            font-family: Fusion-Pixel-12-proportional-zh_hans, sans-serif;
            font-size: 24px;
            border-color: #00adef;
            border-width: 1px;
            border-style: solid;
            border-radius: 16px;
            line-height: 40px;
            display: inline-block;
        }
    </style>
</head>
<body>
<div class="ruler-1"></div>
<div class="ruler-2"></div>
<div class="ruler-3"></div>
<div class="gui">
    <div class="font-1">􀎞􀆉􀐫􀅈按钮</div>
    <div class="font-2">􀎞􀆉􀐫􀅈按钮</div>
    <div class="font-3">􀎞􀆉􀐫􀅈</div>
    <div class="font-4">按钮</div>
</div>
</body>
</html>

https://static.takwolf.com/github/ark-pixel-font/issues/33/index2.html

上下左右各留1px,相当于字间距为 2px

image

上:1px 字间距(当前配置)
下:2px 字间距

备注:chrome 自带抗锯齿,为保持效果明显,已关闭该属性

commented

就是这1px(上和右),在界面会很明显,是否明显取决于整体设计是否会突出这点,如果毫无线框则不那么的突出,但这几乎不能避免,因为你的按钮无论是边框还是底色块总会存在一些边缘设计。字体是按照12px设计,那么当指定字号为12px时,我们知道偏移的是1px,而字号显示为13px或者假设是24px时,同比放大的偏移是2px。你量一量按钮4文字边缘到按钮边框的上边距离是10px,下边距离是8px。

刚刚我尝试了几个其它非点阵。

前文提到的 猫啃什锦黑 的基线和留白结果看上去是与苹方一致的。

接着我试了 猫啃珠圆体 它是略微偏上一点点,半像素大概。

接着 寒蝉圆黑体 就整个走位了。

后两个是我昨晚我在手机上对比了一些字体看着不错的,可惜也都漂移了,最初那个 猫啃什锦黑 倒是对齐很好,就是阅读起来费劲。这种问题很糟心,这导致这些字体不能全方面的覆盖到整个程序界面,而只能是:比如,阅读文章时的正文部分,但实际上正文部分反而不需要它们,因为正文最适合的是像系统自带的黑体而不是具有个性化的它们。

--

你写的demo中是对的,情况就是这样,现在我们知道这个偏移是来自留白,而不是基线方面,所以你怎么排它们都是一样的,多出来的就是上方和右方的1px。

也就是我一直描述的,增加1px对称位置它就没有对齐问题了(或裁剪掉留白,但这不符合其它场景对字体的使用,字间距问题。如果我们能接受且觉得增加1px留白后的间距2px是美观的,那么这会是最好的方案)。

--

标准。差不多每个操作系统都在带的 Arial 可以代替 SF Pro 或 苹方 放在首选位置(当与其它字体对比偏移时)。即,最好的情况是跟它们一样,保持一致的,也留白对称的。字体设计者可能真的有很多使用不对称留白处理问题,但不够细想后续问题而出更好的折中方案。

==

没错。增加对称留白会间距拉大(上下可能无所谓。左右距离,也就是我感觉你可能在意这点,从1px变成2px。但 我倒是无所谓这点。换个角度想想,还有字体刻意拉更大距离,到底是否1px距离就最好也不一定那么绝对。)。

commented

很难找能用的字体,大部分都存在偏移,除了系统自带的,和个别可能考虑到这点的。这个问题于界面的严肃性在于,我们看自己的一些设计界面时用到它,有些情况可能不明显,但试想操作系统的时钟文字偏移了,以及apple甚至会特意为分钟与秒钟之间的:做垂直对称的特殊处理,显然,它是很重要的。(让字号继续保持原本,而缩减笔画让上下左右等边留白1px(尚不清楚设计字体角度减少这1px的难度),这则显然在字体已经做了的情况下是无法重来的。只能扩充像素。)。如果是从头做字体时,可以考虑到这个问题和字号平衡下,看如何达到能等边留白。

如果用户的屏幕是正好2x的。0.5px的对称留白不知道会显示为什么样,是否会模糊(还是,刚好0.5+0.5。。。1px?),但这不符合低像素环境。

你能按照我提供的 demo 的思路,复现一下这张图

image

上下边距的具体尺寸数值吗

commented

此时字号13px。

Screenshot 2023-11-08 15 44 44

这张图用的是monospaced版本。【右上角按钮:上边距6px、下边距4.5px〖文件图标上下均4.5px〗】【左下角无图标观测文字左右:左边距7px、右边距8px】

Screenshot 2023-11-08 15 45 39

当使用proportional版本时,文字不会往下飘(非常细微,垂直几乎没有问题)。【右上角按钮:上边距5px、下边距6px〖文件图标上下均4.5px〗】【左下角无图标观测文字左右:左边距7px、右边距8px】

--

proportional版本让视觉上垂直位置的问题基本消除,但这无法消除右边距的1px。

当我们把视角拉远,看到多几个。

Screenshot 2023-11-08 15 52 55

proportional的略微上偏移,会在右边距多1px的情况下,组合出它仍然有视觉上比较明显的偏移,即 整个看上去 文字在框体里偏左上。proportional使垂直得到了很大的改善,但仍然有细微偏移以及右边问题仍然存在。

Screenshot 2023-11-08 15 57 04

看 电影、电视 和它上方的图标,右侧留白的1px在这种情况会明显。

commented

即,你的demo是proportional版确实垂直位置基本解决,尽管不知道为什么反向上偏移细微一点。而后接着这没能解决的是右边。这个,我应该不用复现,你写的demo的情况和我实际用在这里的情况是一样的。

如果说不偏移是满分。proportional能让垂直变好,这样是满分的2/3,垂直比水平重要,剩下的1分是莫名反向上的细微,以及右侧1px,在个别位置仍然是明显的。

等宽模式是一个特殊的版本,12px 中基线位置在 -2px,所以按照基线对齐,文字会偏下,西文和符号会偏上。该参数是故意设定的,以保证在一些特殊尺寸环境下,例如液晶屏只有12px 高,保证所有字符均可显示。

参考读我:https://github.com/TakWolf/ark-pixel-font#%E5%AE%BD%E5%BA%A6%E6%A8%A1%E5%BC%8F

「等宽」模式
字符为全宽或半宽,排版时可严格对其。字形完全处于字面框内部,默认行高等于字体的像素尺寸。

但基线位置略微偏高,中西文混排时西文在视觉上重心偏高,美观性略差。

「比例」模式
字符宽度根据字形实际情况变化,基线处于合适的位置。纵向上字形可能会超出字面框,默认行高大于字体的像素尺寸。

该模式排版观感自然,如无特殊需求,你应该优先选择这个模式。

commented

等宽是出于我平时对等宽的理解,因为要显示一些数字:比如01,02,要等宽在排版上好一些,以及比如显示代码。这里可能有我的一些误解,更多时候我将等宽视为数字与英文与标点这些可以等宽,尤其用于显示代码。

后半段开始主要是用空像素留白导致的剩余的右侧1px,即字间距需求,和界面制作时不需要这1px的矛盾。

现在proportional版的向上反偏移是:这样去看,monospaced的上下差距是1.5px,而proportional是1px,且方向相反。此处确实缩小了0.5px是有作用的,以及视觉上可能向上偏移比向下偏移会感觉模糊一些,这可能也联系到左边的那个文件图标的上方有个折角带来的组合影响,但无论如何是小了0.5px距离。

==

← ← but,所以还是字体本身等边可能最好。

你说的更换了比例模式后,文字反而偏上,是因为 SF-Pro 字体自身行高本身带有一个不正确的偏移。参考这个上面的图:

image

单独使用 SF-Pro 或者设置为主字体是,会自带一个偏移量,导致不对齐。但是文字是按照基线对齐的,所以会偏上。

你会看到,文字始终按照基线对齐。而边框则包裹字形实际空间。正确的显示位置,应该是边框紧贴顶部。

我现在不确定为什么 SF-Pro 会有这个偏移,具体可能需要解包字体来看

commented

喔,第一次将字号改为12px。确实犀利很多,点对点是好看。

--

向上偏移。

我同意你的结论。不过我们现在遇到个情况是,这个不正确的偏移。是无论前面是Arial、Apple Color Emoji、还是SF Pro,都有的一个偏移,也就是说,即使Arial这个每个系统都带的字体也将其视为默认(我刚刚测试了,除非前面这三个哪个都不带才能刚好上下都是5.5px,否则就会有这个偏移)。—— 即 某种角度,如果我们要让字体的proportional版的偏移与它们一致,那么可能要跟它们一样使用这个错误的值,否则混排会偏上。

等等。我想起来,前面我提到其它几个字体。猫啃什锦黑 属于是做的和这些系统字体一样,而 猫啃珠圆体 则是和 ark-pixel proportional版一样 略微向上1px反过来。这个可能可以考虑一下,是匹配哪种更好(此处 尽管对我而言需要的是和操作系统一致的值,但如果这是个错误偏移,也不否认字体不这样偏移。暂不清楚这个这个正确与否如何定义更好,可能取决于字体用于其它场景时的情况,是否这会造成问题,它不属于标准)。

我不太清楚苹果的字体设计规范。以下是对思源黑体的测试:

https://static.takwolf.com/github/ark-pixel-font/issues/33/index3.html

image

左侧为 Fusion-Pixel,中间思源。边框位置正确,右侧为苹方,顶部有偏移。

实际发现思源、苹方汉字顶部也存在一段空白。即在行高中,汉字不是垂直居中的,而是略微偏下。

commented

这就对了 ← ← 我过去试过思源,由于存在这个偏移而没用,用了苹方(要不要一并看看雅黑,雅黑我给忘了什么结论了)。而这里你是按照与思源一致的,这个事情是它们的决定有些不一致。浏览器环境中哪怕自家的Chrome的Noto Sans CJK SC也是上下差距1px的(因此如果考虑浏览器,这里谷歌用的字体的做法应该还不如带偏移的苹果实际)。

emmm。我电脑里的雅黑在macOS中量出来是,Microsoft YaHei会偏移一点,Microsoft YaHei UI会偏移更多一点,这两个都是介于思源和苹方之间。与实际使用中显示的一样,雅黑多数小字号下会相差不是1px而是0.5px。这里,按照浏览器的结果,是应该按照苹果的能上下一致(因为测试的浏览器就是谷歌家的,它自己不对齐自己的字的话没法当那个正确的标准去看待。否则结果应该是思源能被对齐而苹方产生了不对齐无法纠正。即 浏览器是按照苹果的对齐一致的)。

--

也就是说。如果其它情况下比如ttf的用途是按照思源这种情况(假设其它情况下,如果按浏览器做这种偏移反而是不正确的,会产生错位的)。那么所要生成的woff2如果要符合浏览器用途,那么要刻意为它做偏移,这个woff2才能垂直对齐正常工作。

commented

我弄了个有意思的web中垂直偏移的修复方式。

@font-face {
  font-family: "FusionPixel";
  src:
    url("/fusion-pixel-12px-proportional-zh_hans.woff2") format("woff")
  ;
  size-adjust: calc(100% - 1/13*100%);
}

通过size-adjust缩小字体,由于文字是按照基线的,偏上1px的意思可以理解为上方多了1px。于是将字体calc缩小1px。当指定字号为13px时,按照这个方式缩小了1px,刚好是12px,垂直是完美对齐上下距离都6px,且= = 刚好符合12px字体原本的状态 点对点很清晰。

https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/size-adjust

只不过size-adjust虽然已经都支持了,但版本要求比较新,比如safari要到17,17应该是现在的最新版。

Screenshot 2023-11-08 18 34 13

(这样也并不完全解决,原因是字体大小由加载时决定,13px的计算只能处理被设置为13px时的位置,其它位置一并按照13px计算,结果会是错误的。)

剩下是 右侧1px问题。emmm...

commented

算了,右侧在没有裁剪接口的情况下是人类无法挑战的。只能以,对所有有边距位置打上class,而后在使用该字体时且到右边比左边小1px(按照前面对13px进行缩放到12px,这个1px不是刚好1px,是1px的calc(100% - 1/13*100%)。)的样式。

OVER。

commented

噢。非常感谢,这样我现在就能使用它了,按照前面的设置为13px但缩放为12px时是实际为12px,在去掉右侧之后,它就会是基本正常的,不再有明显问题,不过整体上要针对较新的浏览器才有效。关于如何完全的裁剪所有留白,或者调整基线,这个未来我自己尝试一下。因为按照目前的情况,如果不学会自己调整,很大一部分字体都不能被使用,如果想允许用户切换多种优秀的字体,就必须得做这个工作。

Web可能只是字体的其中一种使用场景,甚至不是设计者的主要考虑。但我还是希望将web这件事作为一种综合考虑,毕竟,一个字体能被无缝的替换进浏览器代替浏览器的默认字体能保持齐整,这应该是一种有益的状态,尤其在现在,寻找能对齐的中文字体都那么难的情况下,有太多字体并未考虑这点,或者像是此字体遵守的思源基线位置却实际情况存在浏览器本身自己不按基线的问题,这些信息 情况。在多数时候,设计人员和开发者可能遇到字体无法适配就算了,去找另一个字体或者就用默认的,因为字体的事情,不能算是不重要,但又不是重要到成为最主要部分,这里,我们展开了挺长的讨论。使用尝试在Web使用中文字体的人当中 应该也是全都会遇到这些情况,出于这些特殊性,可能两个功能的工作者很少知道对方遇到的问题。

当大部分字体都是默认会有不少走位时,emmm 除了掌握自己去调整,似乎也没别的办法能改善,即使我们讨论了一堆,也无法改变整体上已经错位的大部分字体。

--

最后,再次感谢你的工作 : )