java - 自定义字体为 Android 中的某些字母组合提供了不正确的字形

标签 java android fonts

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

enter image description here

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

单独的 IJ 字形都存在于字体中,如果我将文本设置为 I J,我可以让它们出现。

enter image description here

它不是 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/

相关文章:

java - 通过 HttpClient 下载无法正常工作

java - Swing 对象: first setText() gets "stuck" when using Mac Java SE 6

java - 在 JLabel 中显示多行文本

java - [Android map API] : Google-play-services prompting update on phone but not in emulator.

python - 为已安装的字体创建标签名称并以字体样式显示字体名称

java.lang.IllegalStateException : The content of the adapter has changed but ListView did not receive a notification in android Studio

android - 无法在自定义 View 中使用 typedarray

c# - OpenCV灰度忽略红色

css - 字体大小是如何计算的?

swift - 样式占位符文本 NSSearchField 和 NSTextField?