自定义字体为Android中的某些字母组合提供了错误的字形

Sur*_*gch 9 java fonts android

我在Android项目中使用自定义字体.出于某种原因,当文本包含字母IJ时,它给出了以下字形:

在此输入图像描述

这似乎是位于\uE2C5字体的PUA区域的字形.

个人IJ字形都存在于字体中,如果我将文本设置为,我可以让它们出现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");
    }
}
Run Code Online (Sandbox Code Playgroud)

字体可以从这里下载.将它放在项目的assets文件夹中.

Che*_*amp 8

我真的不能说你看到你所看到的东西的原因,但"IJ"的字母组合似乎有特殊待遇的历史.来自印刷结扎的维基百科页面.

然而,荷兰语is更加含糊不清.根据所使用的标准,它可以被认为是有向图,结扎线或字母本身,它的大写和小写形式通常作为单个字形提供,在几种专业字体(例如Zapfino)中具有独特的结合.在荷兰流行的Sans serif大写字母IJ字形通常使用类似U的结扎,左手中风.

也来自维基百科:

字形替换和组成

对于符合Unicode标准的文本处理和显示软件,某些兼容性字符是完全可有可无的.这些包括:

连字拉丁字母中的诸如"ffi"之类的连字通常被编码为传统字符集中的单独字符.Unicode的连字方法是将它们视为富文本,如果启用,则通过字形替换来处理.

鉴于此,我的猜测是你使用的字体已经利用这种用法来做自己的事情.

更新 使用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");
    }
}
Run Code Online (Sandbox Code Playgroud)