我在我的 Android 项目中使用自定义字体。出于某种原因,当文本包含字母 IJ
时,它给了我以下字形:
这似乎是位于字体 PUA 区域的 \uE2C5
处的字形。
单独的 I
和 J
字形都存在于字体中,如果我将文本设置为 I J
,我可以让它们出现。
它不是 OpenType 字体(我认为 Android 甚至不支持自定义字体中的 OpenType 呈现),所以不应该发生这种情况。这是怎么回事?
以下简单项目可重现该问题:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.textview);
Typeface tf = Typeface.createFromAsset(this.getAssets(), "MenksoftHawang.ttf");
textView.setTypeface(tf);
textView.setText("IJ");
}
}
字体可以从here下载.放在项目的assets文件夹中。
最佳答案
我真的不能说你看到你所看到的原因,但“IJ”的字母组合似乎有特殊待遇的历史。来自 Typographic ligature 上的维基百科页面.
Dutch ij, however, is somewhat more ambiguous. Depending on the standard used, it can be considered a digraph, a ligature or a letter in itself, and its upper case and lower case forms are often available as a single glyph with a distinctive ligature in several professional fonts (e.g. Zapfino). Sans serif uppercase IJ glyphs, popular in the Netherlands, typically use a ligature resembling a U with a broken left-hand stroke.
同样来自 Wikipedia :
Glyph substitution and composition
Some compatibility characters are completely dispensable for text processing and display software that conforms to the Unicode standard. These include:
Ligatures Ligatures such as ‘ffi’ in the Latin script were often encoded as a separate character in legacy character sets. Unicode’s approach to ligatures is to treat them as rich text and, if turned on, handled through glyph substitution.
鉴于此,我的猜测是您使用的字体利用了这种用法来做它自己的事情。
更新
使用 setFontFeatureSettings()
可以禁用字形的显示,如以下代码所示。不幸的是,这仅适用于 API 21+。需要注意的是,您可能会意识到其他副作用。
对于21以下的API,可以使用FontForge等字体编辑程序,将U+E2C5处的字形删除。我已经这样做了,它确实消除了字形。只要您认为您可以识别所有可以产生字形的字母组合,这可能是最好的方法。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String features = "\"liga\"=0";
TextView textView = (TextView) findViewById(R.id.textview);
Typeface tf = Typeface.createFromAsset(this.getAssets(), "MenksoftHawang" +
".ttf");
textView.setTypeface(tf);
textView.setFontFeatureSettings(features);
textView.setText("IJ ij");
}
}
关于java - 自定义字体为 Android 中的某些字母组合提供了不正确的字形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43089334/