If you’re a WEB developer, you’re probably familiar with the font-family property of CSS. Usually we set a long list of fonts (family) for the font-family property, like this:

.text { font-family: Menlo, Monaco, Consolas, "Courier New", monospace, Arial, "Microsoft YaHei"."Black"."宋体", sans-serif; }
Copy the code

Why, one might ask? If you are careful enough, you will notice that the English and Chinese fonts are not the same when you browse the website, and the fonts are not the same if you see the website on different operating systems or even different computers. Why is that?

In addition, when you use Microsoft Word for paragraph layout, you will find that Word can automatically apply Chinese fonts to Chinese styles and English fonts to English styles. How does this work?

In the actual typesetting requirements, we usually need to set different fonts for scripts of different languages in order to achieve the best visual effect. Of course, for us, the most common is mixed Chinese and English. Usually designers give beautiful design drafts, but Chinese and English use different fonts, how can we developers restore the original design of the design drafts with high fidelity?

Obviously, for WEB developers, there is a good solution, but for those of you who are on other clients, this is probably a bit of a struggle, and we often tell designers things like “the system doesn’t support it” or “it can’t do it”. In fact, can it be done at all? The answer is yes.

To do this, let’s first look at a concept: the fallback mechanism.

This system usually prescribs fonts for Western languages such as Latin, Cyrillic, and Greek first, and then, in a certain order, the fonts for Arabic, Hindu (for example), Japanese, Korean, simplified Chinese, and traditional Chinese. The text engine will try to display the characters it encounters in the preferred font, and if the font at the top of the Fallback list does not support the character, it will look backward (this is called a fallback). The font-family property of CSS basically works the same way.

Windows is similar. Windows 7 currently has the western font Segoe UI, the simplified Chinese font Microsoft Yahei, the traditional Chinese font Microsoft Orthohei, the Japanese font Meiryo, and the Sky City font Mangal… So you don’t need software like that, your operating system already does that.

Because Chinese, Japanese and Korean characters share Unicode code point, when a character (such as “zhi”) is supported in simplified Chinese, traditional Chinese, Japanese, and Korean fonts, the operating system selects the preferred writing system font based on the current locale and the order of the system language list.

However, very little has been said about fallback fonts on mobile operating systems, let alone implemented, but I’ve been looking around and found some clues. Since I’m an iOS developer, let’s use iOS as an example to see how it can be implemented.

In general, we create a font as follows:

let systemFont = UIFont.systemFont(ofSize: fontSize)
Copy the code

Obviously, if you build it this way, you won’t achieve our goals. So how do you do that? We need to use UIFontDescriptor, like this:

public extension UIFont {
    convenience init(names: [String], size: CGFloat) {
        
        ifnames.first ! =nil {
            let mainFontName = names.first!
            
            let descriptors = names.map { UIFontDescriptor(fontAttributes: [.name: $0])}let attributes: [UIFontDescriptor.AttributeName: Any] = [
                UIFontDescriptor.AttributeName.cascadeList: descriptors,
                UIFontDescriptor.AttributeName.name: mainFontName,
                UIFontDescriptor.AttributeName.size: size,
                ]
            
            let customFontDescriptor: UIFontDescriptor = UIFontDescriptor(fontAttributes: attributes)
            self.init(descriptor: customFontDescriptor, size: size)
        }
        else{
            let systemFont = UIFont.systemFont(ofSize: size)
            let systemFontDescriptor: UIFontDescriptor = systemFont.fontDescriptor
            self.init(descriptor: systemFontDescriptor, size: size)
        }
    }
    
    convenience init(families: [String], size: CGFloat, weight: UIFont.Weight = .regular) {
        
        iffamilies.first ! =nil {
            let mainFontFamily = families.first!
            let descriptors = families.map { UIFontDescriptor(fontAttributes: [.family: $0])}let traits = [UIFontDescriptor.TraitKey.weight: weight]
            
            let attributes: [UIFontDescriptor.AttributeName: Any] = [
                UIFontDescriptor.AttributeName.cascadeList: descriptors,
                UIFontDescriptor.AttributeName.family: mainFontFamily,
                UIFontDescriptor.AttributeName.size: size,
                UIFontDescriptor.AttributeName.traits: traits
            ]
            
            let customFontDescriptor: UIFontDescriptor = UIFontDescriptor(fontAttributes: attributes)
            self.init(descriptor: customFontDescriptor, size: size)
        }
        else{
            let systemFont = UIFont.systemFont(ofSize: size, weight: weight)
            let systemFontDescriptor: UIFontDescriptor = systemFont.fontDescriptor
            self.init(descriptor: systemFontDescriptor, size: size)
        }
    }
}
Copy the code

Call example:

let text = Japanese essay in ways of Roman Text messaging on behalf of Japan. The Language I ヒ raijin-ギ Ada San Francisco 1906 Japanese and ロ 漢 ー verbal Verbal passed the book to esque. System Font フ chu ト and can hugging alone with five years of work. \ n \ n あ の イ ー ハ ト ー ヴ ォ の \ n す き と お っ た summer wind, \ n で も bottom に cold た さ を も つ green い そ ら, \ n う つ く し い sen で act the role ofing ら れ た モ ー リ オ outside city, \ n の ぎ ら ぎ ら ひ か る grass の wave. \n1234567890iClockᴹᴵᴺᴵClockªMINI \nABCDEFGHIJKLM\ n1234567890iClockᴹᴵᴺᴵClockªMINI"
let font = UIFont(families: ["Lucida Grande"."Baskerville"."Apple SD Gothic Neo"], size: 20, weight: .medium)
//let font = UIFont(names: ["LucidaGrande", "Baskerville", "AppleSDGothicNeo-Thin"], size: 20)
label.font = font
label.text = text
Copy the code

Font-family: ‘family’, ‘font name’, ‘family’, ‘font name’, ‘family’, ‘font name’…

If the font is customized, you can also upload the font to the App for viewing on the LAN of the same wifi.

Demo animation:

Github source: github.com/pcjbird/fbC…

The original link: blog.lessney.com/blog/2019/1…

Reference links:

Is there software that can specify different fonts for text in different languages?

www.zhihu.com/question/20…

Fallback to pure Japanese font. No more Chinese font in Japanese text on iOS apps.

Github.com/usagimaru/F…