Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 自定义字体为Android中的某些字母组合提供了不正确的字形_Java_Android_Fonts - Fatal编程技术网

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

Java 自定义字体为Android中的某些字母组合提供了不正确的字形,java,android,fonts,Java,Android,Fonts,我在Android项目中使用自定义字体。出于某种原因,当文本包含字母IJ时,它会给出以下标志符号: 这似乎是位于字体PUA区域\uE2C5的标志符号 单个I和J字形都存在于字体中,如果我将文本设置为I J,我可以让它们出现 它不是OpenType字体(我认为Android甚至不支持自定义字体中的OpenType渲染),所以不应该发生类似的事情。这是怎么回事 以下简单项目可重现该问题: public class MainActivity extends AppCompatActivity {

我在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");
    }
}

字体可从下载。将其放在项目的“资产”文件夹中

我不确定问题的确切原因,我想可能也是字体问题

但作为一种解决方法,您可以应用微小的字母间距,这将显示预期的字母

textView1.setText("IJ");

textView2.setLetterSpacing(0.04f);
textView2.setText("IJ");
结果:


我真的无法解释你看到你看到的东西的原因,但“IJ”的字母组合似乎有特殊处理的历史。从上的维基百科页面

然而,达奇的说法有些模棱两可。根据所使用的标准,它本身可以被视为有向图、连字或字母,其大写和小写形式通常可以作为一个单独的字形,在几种专业字体(例如Zapfino)中使用独特的连字。无衬线大写字母IJ字形在荷兰很流行,通常使用类似于U的连字,左手划破

也来自:

字形替换和组合

一些兼容字符对于符合Unicode标准的文本处理和显示软件来说是完全不必要的。这些措施包括:

结扎 拉丁文字中的连字(如“ffi”)通常在传统字符集中作为单独的字符进行编码。Unicode处理连字的方法是将其视为富文本,如果启用,则通过glyph替换进行处理

鉴于此,我猜测您使用的字体利用了这种用法来完成自己的工作

更新 使用
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");
    }
}

这个问题似乎有三种解决方案:

1.以编程方式禁用连字 您可以使用
setFontFeatureSettings
(建议)或
setletSpacing
(建议)以编程方式禁用连字。这两种方法的一个缺点是它们只能从API 21中获得

2.编辑字体以外的连字 您可以使用字体编辑软件修复或删除字体中的连字错误。有关如何在FontForge中执行此操作的信息,请参见。这里的一个潜在问题是字体版权所有者可能不允许第三方编辑其字体

3.使用不同的字体 不同的字体经常可用,在这种情况下也是如此。问题中有问题的TrueType字体的同一家公司也有该字体的OpenType版本。OpenType版本似乎没有连字错误。不过,它的一个缺点是,它的大小要大得多,这会使应用程序下载的大小变大

笔记
  • 我以前认为在Android 6.0之前没有连字渲染。然而,TrueType字体显然支持一些基本连字,这些连字在6.0之前的Android版本中呈现
  • FontForge的下图显示了问题中引用的有问题字体中定义的所有连字。

有趣!这让我很好奇为什么会发生这种情况。以及为什么设置字母间距会阻止它。注意:设置字母间距仅在API 21中可用。我不知道这一点。
ij
ij
都会生成其他字符。而
fi
会产生一个空格。这听起来可能就是原因。你知道我会在字体文件中查找到什么吗?@Suragch你想更改字形还是禁用字形,使“IJ”、“IJ”显示为两个单独的字母?有字体编辑器可用于编辑TrueType字体。粗略地看,在这些编辑器中,字形的处理方式可能有所不同,因此您需要确保编辑器是“字形感知的”。我没有做过任何此类编辑,因此我不能推荐其中一种。我看到其他人提到azizbekian的解决方案,即改变间距,然后“将其切掉”,作为一种解决方法。我想禁用它,以便它们显示为两个不同的字母。我以前用FontForge做过一些字体编辑,但没有用连字。我的印象是只有OpenType字体能做到这一点(而且在6.0版之前的Android中不支持OpenType渲染)。@Suragh关于TTF和连字支持的问题问得好。可能有一些从苹果继承来的特殊情况?在此搜索“线路布局管理器”。(很抱歉维基百科上有这么多参考资料。)第二个是行布局管理器,它可以对特定的字符序列进行编码,以便在某些情况下翻转到不同的设计,例如为“fi”、“ffi”、“ct”提供连字,等等,同时维护拼写检查和文本搜索所需的字符备份存储。@Suragch还有一件事。看看这是
T的一部分