检查自定义字体可以显示的字符(Check if custom font can display ch

2019-06-26 18:21发布

我有这显示框字符自定义字体。 我使用的是不支持的所有语言明显的字体。 我想检查我要显示的字符串可以通过我的自定义的字体显示。 如果它不能然后我想使用标准的Android字体(我知道可以显示字符)。 我找不到来检查,如果我的字样虽然可以显示一个特定字符串的方法。 我相信我所看到的身边,做这个地方的方法。 任何人都知道吗?

Answer 1:

更新:如果你编码API等级23以上,请使用Paint.hasGlyph()中所提到的由奥森·贝恩斯的答案 。 否则,请参见下面我原来的答复。


当你在自己的答复中提到有没有内置的用于检查此方法。 但是,如果你有过要检查什么字符串/字符一定的控制,但实际上可能是一个稍微更具创造性的方式来做到这一点。

你可以画出你知道缺少在您要检查,然后绘制你想知道它是否存在一个字符,最后对它们进行比较,看看他们看起来是一样的字体字符。

这是说明我是如何实现这个检查一个代码示例:

public Bitmap drawBitmap(String text){
    Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, Bitmap.Config.ALPHA_8);
    Canvas c = new Canvas(b);
    c.drawText(text, 0, BITMAP_HEIGHT / 2, paint);
    return b;
}

public byte[] getPixels(Bitmap b) {
    ByteBuffer buffer = ByteBuffer.allocate(b.getByteCount());
    b.copyPixelsToBuffer(buffer);
    return buffer.array();
}
public boolean isCharacterMissingInFont(String ch) {
    String missingCharacter = "\u0978"; // reserved code point in the devanagari block (should not exist).
    byte[] b1 = getPixels(drawBitmap(ch));
    byte[] b2 = getPixels(drawBitmap(missingCharacter));
    return Arrays.equals(b1, b2);
}

还有要记住用这种方法的一些重要的限制:

  • 您检查字符(参数isCharacterMissing )必须是无空格(可以通过使用检测Character.isWhitespace() )。 在某些字体丢失字符呈现为空白,因此,如果您比较会存在会错误地报告为这样的字体缺少的字符空格字符。
  • 所述missingCharacter构件必须是已知的字体中缺少要被检查的字符。 该代码点U + 0978 ,我现在用的就是在梵文的Unicode块,因此目前应该在所有兼容Unicode字体缺少的中间预留的代码点,但在未来,当新的字符添加到Unicode的代码点可能被分配到一个真实的人物。 所以这种做法是不面向未来的,但如果你自己提供的字体可以确保无论何时更改应用程序的字体您使用的是丢失字符。
  • 由于此检查是通过绘制位图,并比较他们做这不是很有效,所以应该只用来检查几个字符,而不是所有字符串在应用程序中。

更新:

该解决方案来看看U + 0978由别人指出长期没有工作。 在加入该字符的Unicode 7.0发布于2014年6月 。 另一种选择是使用中存在的unicode字形,但是这是非常不可能以正常字体使用。

U + 124AB在早期王朝楔形块可能是一些并不在很多字体都存在。



Answer 2:

由于Android版本23,你可以像这样的测试:

Typeface typeface;
//initialize the custom font here

//enter the character to test
String charToTest="\u0978";
Paint paint=new Paint();
paint.setTypeface(typeface);
boolean hasGlyph=paint.hasGlyph(charToTest);


Answer 3:

@nibarius回答运作良好,虽然有不同的字符:“\ u2936”。

然而,该解决方案是在内存,CPU和时间重。 我需要一个非常小的数字字符的解决方案,所以我只检查范围实施了“快速和肮脏”的解决方案。 它的工作原理快约50倍倍,所以它更适合我的情况:

public boolean isCharGlyphAvailable(char... c) {
      Rect missingCharBounds = new Rect();
      char missingCharacter = '\u2936';
      paint.getTextBounds(c, 0, 1, missingCharBounds); // takes array as argument, but I need only one char.
      Rect testCharsBounds = new Rect();
      paint.getTextBounds(c, 0, 1, testCharsBounds);
      return !testCharsBounds.equals(missingCharBounds);
}

我要提醒的是这种方法比@nibarius不太准确,并有一定的假阴性和假阳性,但如果你只需要以能够退却到其他字符,测试几个大字 - 该解决方案是伟大的。



Answer 4:

请从源代码谷歌Mozc项目。 该EmojiRenderableChecker类似乎工作得很好!

它就像一个COMPAT版本Paint.hasGlypgh (在棉花糖添加)。



Answer 5:

对于那些你们谁仍然想你的应用程序是兼容的API小于23,仍然使用hasGlyph功能在你的代码,你可以使用以下方式@TargetApi(23):

@TargetApi(23)
public boolean isPrintable( String c ) {
    Paint paint=new Paint();
    boolean hasGlyph=true;
    hasGlyph=paint.hasGlyph(c);
    return hasGlyph;
}

然后在你的代码:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    if(isPrintable(yourString)) {
        //Do Something
    }
}

唯一的问题是,在API的超过23时,你的应用程序可能会显示空白的符号。 但至少在API23 +您的应用程序将是完美的。



Answer 6:

要检查的音乐符号♫是否正在显示的字符串(如果不被某些设备上显示它),你可以尝试测量字符串的宽度; if width == 0 ,则符号是不存在的。

Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Rect rtt = new Rect();
paint.getTextBounds( "♫", 0, 1, rtt );
    if( rtt.width() == 0 ){
}


文章来源: Check if custom font can display character