UIFont monospacedDigitSystemFont doesn't work

Dear Experts,

Does monospacedDigitSystemFont work for others? It is supposed to be a font where digits are monospaced, but other characters aren't. This is especially useful for things like counter widgets, where you don't want the total length of the string to fluctuate as it updates.

When I try to use it I get the same results as for the regular system font, i.e. digit 1 is narrower than the others.

[UIFont monospacedSystemFont...] does work correctly.

When I do this:

UIFont* uifont = [UIFont systemFontOfSize: sz weight: UIFontWeightRegular];
NSLog(@"font attributes: %@",uifont.fontDescriptor.fontAttributes);

I get:

font attributes: {
    NSCTFontUIUsageAttribute = CTFontRegularUsage;
    NSFontSizeAttribute = 64;
}

When I change it to monospacedDigitSystemFontOfSize:, I get this:

font attributes: {
    NSCTFontFeatureSettingsAttribute =     (
        {
            CTFeatureSelectorIdentifier = 0;
            CTFeatureTypeIdentifier = 6;
        }
    );
    NSCTFontUIUsageAttribute = CTFontRegularUsage;
    NSFontSizeAttribute = 64;
}

So presumably that "feature settings attribute" with values 0,6 is the thing that gives it monospaced digits. Question: is that documented somewhere?

Now, what I do with that UIFont is:

  CTFontDescriptorRef descr = (__bridge CTFontDescriptorRef)uifont.fontDescriptor;
  CTFontRef font = CTFontCreateWithFontDescriptor(descr, sz, nullptr);

(I do that, because I never found a way to ask for monospaced-digits at the Core Text level.)

Now I look up the advances for the digits:

  char16_t digits[] = u"0123456789";
  CGGlyph glyphs[10];
  CTFontGetGlyphsForCharacters(font, (const UniChar*)digits, glyphs, 10);
  
  CGSize advances[10];
  CTFontGetAdvancesForGlyphs(font, kCTFontOrientationHorizontal, glyphs, advances, 10);
  for (int i = 0; i < 10; ++i) {
    NSLog(@"digit = %d, advance = %f",i,advances[i].width);
  }

and I get this:

digit = 0, advance = 39.031250
digit = 1, advance = 28.593750
digit = 2, advance = 36.437500
digit = 3, advance = 38.093750
digit = 4, advance = 38.906250
digit = 5, advance = 37.656250
digit = 6, advance = 39.718750
digit = 7, advance = 35.218750
digit = 8, advance = 38.593750
digit = 9, advance = 39.718750

Those clearly aren't equal.

What's going on here? Does Core Text support monospaced digits, or is it something that is added at the UIKit level? If Core Text does support it, do I need to do something to my CTFontDescriptor to get it? Or maybe I should be looking at something other than the advances?

So presumably that "feature settings attribute" with values 0,6 is the thing that gives it monospaced digits. Question: is that documented somewhere?

It turns out that 0 is kMonospacedNumbersSelector and 6 is kNumberSpacing, where are documented here: https://developer-rno.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type6 - not that the developer.apple.com search can find it.

UIFont monospacedDigitSystemFont doesn't work
 
 
Q