Reputation: 512446
I'm using a custom font in my Android project. For some reason when the text includes the letters IJ
together, it gives me the following glyph:
This appears to be the glyph located at \uE2C5
of the PUA region of the font.
The individual I
and J
glyphs both exist in the font and I can get them to appear if I set the text to I J
.
It's not an OpenType font (I don't think Android even supports OpenType rendering in custom fonts), so there shouldn't be anything like this happening. What is going on here?
The problem is reproducible with the following simple project:
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");
}
}
The font can be downloaded from here. Put it in the assets folder in the project.
Upvotes: 11
Views: 1941
Reputation: 512446
There appears to be three solutions to this problem:
You can disable the ligatures programmatically with setFontFeatureSettings
(as suggested here) or setLetterSpacing
(as suggested here). One disadvantage of both of these methods is that they are only available from API 21.
You can use font editing software to fix or delete the ligature errors in the font. See this Q&A for how to do it in FontForge. A potential problem here is that the font copyright owners may not allow third parties to edit their fonts.
Different fonts are often available and that is true in this case. The same company that had the problematic TrueType font in the question also has an OpenType version of that font. The OpenType version does not seem to have the ligature errors. A disadvantage, though, is that it is significantly larger in size, which will make that app download size larger.
Upvotes: 3
Reputation: 62841
I can't really speak to the reason that you are seeing what you are seeing, but the letter combination of "IJ" seems to have a history of special treatment. From the Wikipedia page on 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.
Also from 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.
Given this, my guess is that the font you are using has taken advantage of this type of usage to do its own thing.
Update
Using setFontFeatureSettings()
works to disable the display of the glyph as shown in the following code. Unfortunately, this is only available in API 21+. There is a caveat that there may be other side effects that you may be become aware of.
For APIs below 21, you can use a font editing program such as FontForge and delete the glyph at U+E2C5. I have done this and it does eliminate the glyph. This may be the best way to go as long as you think that you can identify all letter combinations that can result in a glyph.
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");
}
}
Upvotes: 9
Reputation: 62199
I'm not sure about exact cause of the issue, I assume it might be also a font issue.
But as a workaround you can apply tiny letter spacing, which will show letters as expected.
textView1.setText("IJ");
textView2.setLetterSpacing(0.04f);
textView2.setText("IJ");
Result:
Upvotes: 4