Search code examples
iosfontsnsattributedstringnsmutableattributedstringkerning

ios NSMutableAttributedString NSKernAttributeName wrong kerning with "fl" and "fi" letters


I'm using attributed strings on labels to change the spacing between letters:

var attributedString=NSMutableAttributedString(string: "Fifi floflo")
attributedString.addAttribute(NSKernAttributeName, value: CGFloat(10), range: NSRange(location: 0, length: attributedString.length))
label.attributedText=attributedString

The kerning is working well excepts for two groups of letters which are "fl" and "fi" (maybe others I didn't see at the moment). I'm using "Avenir-medium" font but I tested with basic Arial font and the problem still occurs.

With the word 'Profile'

With the word "Fifi floflo'


Solution

  • NSAttributedStrings come with ligatures enabled by default. Ligatures combine overhanging character combinations into single glyphs. If you are applying letter spacing, you will want to disable them - otherwise those letter-pair glyphs won't separate.

    attributedString.addAttribute(NSLigatureAttributeName, 
      value:0, 
      range: NSRange(location: 0, length: attributedString.length))
    

    From the docs:

    NSLigatureAttributeName

    The value of this attribute is an NSNumber object containing an integer. Ligatures cause specific character combinations to be rendered using a single custom glyph that corresponds to those characters. The value 0 indicates no ligatures. The value 1 indicates the use of the default ligatures. The value 2 indicates the use of all ligatures. The default value for this attribute is 1. (Value 2 is unsupported on iOS.)