DIllion Daniels
DIllion Daniels

Reputation: 7

Get surrogate pairs from an emoji

What I'm trying to do is check if an emoji can be rendered on the iOS device by using this:

    let font = CTFontCreateWithName("AppleColorEmoji", 12, nil)
    var code_point: [UniChar] = [0xD83D, 0xDE0D]
    var glyphs: [CGGlyph] = [0, 0]
    let has_glyph = CTFontGetGlyphsForCharacters(font, &code_point, &glyphs, 2)

    if has_glyph == false {
        return false
    }
    else {
        return true
    }

It takes two code points and checks if the emoji can be rendered. Now what I'm having trouble with is how do I get the surrogate pairs directly from an emoji. I've Googled around and I can't seem to find any way to do so. Any ideas?

Upvotes: 0

Views: 1722

Answers (2)

Martin R
Martin R

Reputation: 539745

What you are looking for is the UTF-16 representation of a character:

let emoji = "😍"
let utf16codepoints = Array(emoji.utf16)

utf16codepoints is an [UInt16] array, and UniChar is a type alias for UInt16, so this array can be used directly in CTFontGetGlyphsForCharacters() to check if a font has a glyph for this character (now updated for Swift 3/4):

let font = CTFontCreateWithName("AppleColorEmoji" as CFString, 12, nil)
var glyphs: [CGGlyph] = [0, 0]
let has_glyph = CTFontGetGlyphsForCharacters(font, utf16codepoints, &glyphs, utf16codepoints.count)
print(has_glyph)
// true

Hex dump the array to verify that it is the same as the code_point array in your question:

print(utf16codepoints.map { String($0, radix: 16)} )
// ["d83d", "de0d"]

print(utf16codepoints == [0xD83D, 0xDE0D])
// true

Upvotes: 1

Mailyan
Mailyan

Reputation: 195

In case somebody is looking for Obj-C implementation:

- (BOOL)isEmojiSupported:(NSString*)emoji
{
    NSUInteger length = [emoji length];

    unichar characters[length + 1];
    [emoji getCharacters:characters range:NSMakeRange(0, length)];
    characters[length] = 0x0; 

    CGGlyph glyphs[length];     
    CTFontRef ctFont = CTFontCreateWithName(CFSTR("AppleColorEmoji"), 12, NULL);
    BOOL ret = CTFontGetGlyphsForCharacters(ctFont, characters, glyphs, emoji.length);
    CFRelease(ctFont);

    return ret;
}

Upvotes: 1

Related Questions