Java字体是否支持所有Unicode码点?读取可用字形数量缺失如何解决
缺失字形的原因
Font.getNumGlyphs()返回的是字体文件包含的所有字形总数,其中不止包含对应单个Unicode码位的常规字形,还包含大量无对应单码位的特殊字形:- 连字(ligature):比如
ff、fi、ffi这类由多个字符组合生成的单个字形 - 替代字形:比如装饰变体、小型大写变体、风格化替代字形这类OpenType特性提供的可选字形
- 控制类字形:比如
.notdef(缺字 fallback 字形)、各类空格、零宽控制符对应的特殊字形
- 连字(ligature):比如
- 你原有逻辑是遍历所有Unicode单个码位,通过
canDisplay()判断是否存在对应字形,自然无法命中上述无对应单码位的字形。Cinzel Regular字体本身内置了大量装饰性变体和连字,刚好就是你缺失的160个字形的来源。
正确遍历所有字形的方案
不要遍历Unicode码位,直接按字形索引遍历即可,参考实现代码:
private static void printAllGlyphs(Font font) { int totalGlyphs = font.getNumGlyphs(); System.out.println("总字形数:" + totalGlyphs); for (int glyphIdx = 0; glyphIdx < totalGlyphs; glyphIdx++) { // 可获取字形名称、字形轮廓等所有信息 String glyphName = font.getGlyphName(glyphIdx); System.out.printf("索引%d:字形名称 %s%n", glyphIdx, glyphName); } }
运行上述代码就能看到所有547个字形的信息,缺失的160个字形的名称基本都是XX.alt/XX.smcp/f_X这类特殊命名的变体/连字字形。
内容的提问来源于stack exchange,提问作者DasBabyPixel
相关产品推荐
相关产品推荐

