Times New Roman superscript and Unicode fallback font

I was using Times New Roman and trying to use superscript numbers, but found out that Times New Roman only has superscript numbers 0, 1, 2, 3, ¹ (like so) and since I'm writing out transcriptions of pinyin, I also need superscript 4, 5, 6, 7. When I do that, the font changes to Lucida Grande automatically. I would like to change the default unicode font/alt font from Lucida Grande to EB Garamond (downloaded from Google) since it more closely resembles Times New Roman and unfortunately, I need to keep the font as close to Times New Roman as possible. Is there a way to change the default the computer chooses to when Times New Roman/alt font fails unicode?

Alternatively, is there a font that looks exactly like Times New Roman that has the superscript numbers 0-9?

2022 laptop, M2, Tahoe 26.6.1

Move post at will if need be.

Answered by DTS Engineer in 896578022

Thanks for the follow-up, and I'm sorry for the back-and-forth between the forums. You are in the right place for this part of the question.

Since this is the software developer forums, here is what you can do from a software developer's point of view.

The behavior you are describing, choosing which font supplies a glyph that the main font is missing, is something an app can control directly. The mechanism is the font cascade list.

Every font has a cascade list: an ordered list of fallback fonts. When the main font does not contain a glyph, the system goes through that list in order. It uses the first font that has the glyph. When an app does not provide its own list, the system uses a default one. That default is most likely choosing the substitute font that appears in place of the missing digits. An app can supply its own cascade list instead, so you decide the order.

For your case, you would build a Times New Roman font whose cascade list puts EB Garamond first. Then any character missing from Times New Roman, such as the superscript digits, comes from EB Garamond instead of the system's default choice.

On macOS, the AppKit API is the cascadeList attribute on NSFontDescriptor:

let base = NSFontDescriptor(fontAttributes: [.family: "Times New Roman"])
let fallback = NSFontDescriptor(fontAttributes: [.family: "EB Garamond"])
let descriptor = base.addingAttributes([.cascadeList: [fallback]])
let font = NSFont(descriptor: descriptor, size: 12)

Text drawn with that font uses your order for fallback. The same thing is available one layer down in Core Text through the kCTFontCascadeListAttribute attribute, if you are working at that level.

There is a second approach as well. Some fonts include real superscript digits as a built-in OpenType feature. When a font provides that feature, an app can turn it on through the featureSettings attribute. The superscripts then come from that same font instead of a fallback. Whether a particular font offers the feature depends on the font itself.

One honest note on scope. Both of these are things an app does for the text it draws itself. They set the fallback order inside your own code. They are not a system-wide preference that changes fonts inside other apps. So this helps if you are writing the software that lays out the text. It is not a setting you can change from outside an app that someone else wrote.

If you build a small app or tool to lay out this text yourself, the cascade list gives you full control. Many useful tools began that way, from one specific need the author wanted to solve.

Please let me know if there are any questions.

For help with fonts, please post in the Apple Support Community. The Apple Developer Forums are for questions about APIs and features intended specifically for developers.

I did. But thanks for the loop error. This is what they said when I posted to there before I posted to here:

"We removed your post “Times New Roman superscript & Unicode font fallback on Tahoe because it contained information about beta software."

We should be able to set the default unicode font per document when it's missing from the main font.

I did. But thanks for the loop error. This is what they said when I posted to there before I posted to here:

"We removed your post “Times New Roman superscript & Unicode font fallback on Tahoe because it contained information about beta software."

You probably included something like this, "2022 laptop, M2, Tahoe 26.6.1". They're very picky about anything beta-related in that forum.

The system automatically choses the best font to represent a given glyph based on a number of different aspects. This is called the font cascade list.

Individual apps can, in theory, modify the cascade list. But you can't as an end user. And to be honest, I can't imagine any 3rd party app providing that level of fine-grained font control.

You'll just need to find a font you can use for all content where you need these superscripts.

Thanks for the follow-up, and I'm sorry for the back-and-forth between the forums. You are in the right place for this part of the question.

Since this is the software developer forums, here is what you can do from a software developer's point of view.

The behavior you are describing, choosing which font supplies a glyph that the main font is missing, is something an app can control directly. The mechanism is the font cascade list.

Every font has a cascade list: an ordered list of fallback fonts. When the main font does not contain a glyph, the system goes through that list in order. It uses the first font that has the glyph. When an app does not provide its own list, the system uses a default one. That default is most likely choosing the substitute font that appears in place of the missing digits. An app can supply its own cascade list instead, so you decide the order.

For your case, you would build a Times New Roman font whose cascade list puts EB Garamond first. Then any character missing from Times New Roman, such as the superscript digits, comes from EB Garamond instead of the system's default choice.

On macOS, the AppKit API is the cascadeList attribute on NSFontDescriptor:

let base = NSFontDescriptor(fontAttributes: [.family: "Times New Roman"])
let fallback = NSFontDescriptor(fontAttributes: [.family: "EB Garamond"])
let descriptor = base.addingAttributes([.cascadeList: [fallback]])
let font = NSFont(descriptor: descriptor, size: 12)

Text drawn with that font uses your order for fallback. The same thing is available one layer down in Core Text through the kCTFontCascadeListAttribute attribute, if you are working at that level.

There is a second approach as well. Some fonts include real superscript digits as a built-in OpenType feature. When a font provides that feature, an app can turn it on through the featureSettings attribute. The superscripts then come from that same font instead of a fallback. Whether a particular font offers the feature depends on the font itself.

One honest note on scope. Both of these are things an app does for the text it draws itself. They set the fallback order inside your own code. They are not a system-wide preference that changes fonts inside other apps. So this helps if you are writing the software that lays out the text. It is not a setting you can change from outside an app that someone else wrote.

If you build a small app or tool to lay out this text yourself, the cascade list gives you full control. Many useful tools began that way, from one specific need the author wanted to solve.

Please let me know if there are any questions.

Times New Roman superscript and Unicode fallback font
 
 
Q