This question is related to CoreText (available among Apple platforms). The langauge is Swift 5.10.
It seems that the CTFontCreateUIFontForLanguage() doesn't return usable results if the given UniChar array contains kanji / emoji.
My attempts:
Suppose that I utilize CTFontCreateUIFontForLanguage() using the following Swift script.
#!/usr/bin/env swift
import CoreText
import Foundation
guard let osFont = CTFontCreateUIFontForLanguage(
.system, 14, "zh-Hant" as CFString
) else {
print("CTFont initiation failed.")
exit(1) // Abortion.
}
extension CTFont {
func glyphs(for string: String) -> [CGGlyph]? {
let arrUTF16 = Array(string.utf16)
var glyphs = [CGGlyph](repeating: 0, count: arrUTF16.count)
let result = CTFontGetGlyphsForCharacters(self, arrUTF16, &glyphs, arrUTF16.count)
return result ? glyphs : nil
}
}
let string = "這是草莓蛋糕。" // NOTE: Edit this line to try various parameters.
let unichars = Array(string.utf16)
var fetchedGlyphs: [CGGlyph]? = osFont.glyphs(for: string)
guard var fetchedGlyphs = fetchedGlyphs else {
print("Screwed. I don't know why it only works with ASCII glyphs.")
exit(1) // Abortion.
}
Note that the CTFont can be replaced by
NSFont.systemFont(ofSize: NSFont.systemFontSize)instead of the one I created above. CTFont and NSFont are toll-free bridgable in Swift 5.
The problem in the case:
The (CTFont instance).glyphs(for:) returns nil if the given string parameter contains kanji and / or emoji characters. One may try with other kanji-only strings or emoji-only strings.
You should use
CTFontCreateForString, or its correspondinginit. This looks up the font in the font cascade list and finds a font that supports as many characters in the given string as possible.