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.
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 (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 corresponding init
. 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.
let string = "你好"
let baseFont = CTFont(.system, size: 14)
let osFont = CTFont(font: baseFont, string: string as CFString, range: CFRange(location: 0, length: string.utf16.count))
if let fetchedGlyphs = osFont.glyphs(for: string) {
print(fetchedGlyphs)
}