How can I find a font containing a given character?

advertisements

I have a font that I use for my app which only uses english characters. I use CoreText to display the text, and I notice that whenever someone enters a character that isn't included in the font (like an Arabic character), then the program hangs at this line:

CTFramesetterCreateFrame(textFramesetter, CFRangeMake(0, 0), textMutablePath, NULL);

I have a couple of questions:

  1. is it possible to know if a certain character is included in a font?
  2. is it possible for the system to find a font that contains the unknown character?

Related: Check if certain character is supported by UIFont


1) Is it possible to know if a certain character is included in a font?

BOOL FontContainsCharacter(UIFont *font, unichar character) {
    NSCharacterSet *characterSet = [font.fontDescriptor objectForKey:UIFontDescriptorCharacterSetAttribute];
    return [characterSet characterIsMember:character];
}

2) Is it possible for the system to find a font that contains the unknown character?

NSArray *FontDescriptorsForFontsContainingCharactersInString(NSString *string) {
    NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:string];
    NSDictionary *fontAttributes = @{UIFontDescriptorCharacterSetAttribute:characterSet};
    UIFontDescriptor *fontDescriptor = [UIFontDescriptor fontDescriptorWithFontAttributes:fontAttributes];
    return [fontDescriptor matchingFontDescriptorsWithMandatoryKeys:nil];
}

For example:

NSLog(@"%d", FontContainsCharacter([UIFont fontWithName:@"Helvetica" size:12], 0x0041)); // "A"
NSLog(@"%d", FontContainsCharacter([UIFont fontWithName:@"Helvetica" size:12], 0x4F60)); // "你"

for (UIFontDescriptor *fontDescriptor in FontDescriptorsForFontsContainingCharactersInString(@"你好")) {
    NSLog(@"%@", [UIFont fontWithDescriptor:fontDescriptor size:12].fontName);
}

Output:

1
0
STHeitiSC-Light
STHeitiSC-Medium
STHeitiTC-Light
STHeitiTC-Medium
HiraKakuProN-W3
HiraKakuProN-W6
HiraMinProN-W3
HiraMinProN-W6