Custom installed font not displayed correctly in UILabel
Asked Answered
S

13

87

I'm trying to use a Helvetica Neue Condensed font which I got from the Adobe Font Collection Pro Package. Unfortunately, it seems to draw incorrectly when I use it within a UILabel.

The line height seems to be calculated correctly (I think), but when the font is displayed, it is aligned to the very top of the bounding box. I called [myLabel sizeToFit] and only adjusted the width to produce this screen capture:

Screen capture of incorrect font rendering

I had the same problem with both the bold and regular version of the font. I was able to pull a version of Helvetica Neue Bold from OSX and put it on my device and it displays fine (green background in above picture).

What could be wrong with the either the font file or my code that would cause it to draw this way?

Simian answered 24/3, 2011 at 4:22 Comment(5)
Could I somehow make a subclass of UIFont that can fix these problems?Simian
+1 - same issue for me. I've tried using ZFont to help with this, and it does help somewhat, but not nearly enough. Might be something amiss with how the leading is interpreted with those custom fonts (no clue, really - but I have to think that may have something to do with it!).Leventhal
Hi! Did you eventually found the solution? Please answer your question if yes. Thanks in advance.Samples
Unfortunately, no, I didn't. And I no long have access to the original font file which caused this problem. I like kolyuchiy's answer.. I only wish I could test it in my specific case.Simian
Just so you know, this has been fixed in iOS7.Complected
M
126

I posted a solution that involves patching ttf font file here:

Here's the solution that worked for my custom font which had the same issue in UILabel, UIButton and such. The problem with the font turned out to be the fact that its ascender property was too small compared to the value of system fonts. Ascender is a vertical whitespace above font's characters. To fix your font you will have to download Apple Font Tool Suite command line utilities. Then take your font and do the following:

~$ ftxdumperfuser -t hhea -A d Bold.ttf

This will create Bold.hhea.xml. Open it with a text editor and increase the value of ascender attribute. You will have to experiment a little to find out the exact value that works best for you. In my case I changed it from 750 to 1200. Then run the utility again with the following command line to merge your changes back into the ttf file:

~$ ftxdumperfuser -t hhea -A f Bold.ttf

Then just use the resulting ttf font in your app.

Madgemadhouse answered 29/11, 2011 at 16:33 Comment(10)
Thanks a lot for suggesting this tool! it can also be used to rename a font by editing the "-t name" section likewise.Nikos
##### ERROR: Could not create a font container from fontName.hhea.xmlMurguia
You can also try Mensis or FontForge. These apps can be used to change ascender property too.Madgemadhouse
You made my day. I was stuck with this problem since several weeks. I can use it quite often!Limey
Please, note, that this by increasing ascender you will increase line spacing – this may be the problem if you have multiline text in your app.Dusen
the answer by Joseph Lin, opening the fonts on Glyphs and saving again, works for both iOS 6 and iOS 7.Ahron
** PLEASE ALSO SEE JOSEPH LIN'S ANSWER BELOW ** You should adjust both ascender and set linegap to zero to ensure good alignment on both iOS 6 and iOS 7!Prow
I tried to install the Apple Font Suite on OS X El Capitan, however it can't be installed because it is not compatible anymore to the current OS X version. Did anyone find a way to get it running on El Capitan?Kammerer
Apple Font Tools cannot install in Macbook Pro El Capitan. See apple.stackexchange.com/questions/211138/… for workarounds.Crabby
If you keep changing values, sometimes Xcode will get stuck. If you think that's the case, restart Xcode.Carlcarla
F
66

So this is a modified version of kolyuchiy's answer.

I opened my font with Glyphs, and then exported it without modifying anything. Somehow, magically, the vertical alignment issue was gone!

What's better is that the new font plays nicely with methods like sizeWithFont:, so it doesn't have the issues mentioned by Joshua.

I took a look at the HHEA table with the command kolyuchiy mentioned, and noticed that Glyphs modified not just the ascender, but also lineGap and numberOfHMetrics for me.

Here's the raw data, before:

versionMajor="1"
versionMinor="0"
ascender="780"
descender="-220"
lineGap="200"
advanceWidthMax="1371"
minLeftSideBearing="-73"
minRightSideBearing="-52"
xMaxExtent="1343"
caretSlopeRise="1"
caretSlopeRun="0"
caretOffset="0"
metricDataFormat="0"
numberOfHMetrics="751"

and after:

versionMajor="1"
versionMinor="0"
ascender="980"
descender="-220"
lineGap="0"
advanceWidthMax="1371"
minLeftSideBearing="-73"
minRightSideBearing="-52"
xMaxExtent="1343"
caretSlopeRise="1"
caretSlopeRun="0"
caretOffset="0"
metricDataFormat="0"
numberOfHMetrics="748"

So the moral of the story- don't just increase the ascender, but modify other related values as well.

I'm no typography expert so I can't really explain the why and how. If anyone can provide a better explanation it'd be greatly appreciated! :)

Falsework answered 28/5, 2013 at 17:28 Comment(4)
After I've saved the TTF I'm using again using Glyphs, the font behaves pretty much the same on iOS 6 and iOS 7. Previously its baseline would be misaligned on iOS 6.Ahron
Thanks for finally figuring this out! Apparently iOS 6 honors the lineGap property, while iOS 7 ignores it. The solution is to make the lineGap 0 and make the ascender correspondingly larger. This is exactly what Glyphs did, and it works on both iOS 6 and iOS 7.Charitycharivari
Yes. Reducing the lineGap to zero (0) and leaving the ascender (at 1991) solved the problem for me with the free "Overpass" font from Fedora. Thank you all for guidance to a solution. Works on Both iOS6 and iOS7.Wethington
I just came to the same conclusion as @phatmann's after several failed attempts with Glyphs and OS X Font Tools. The thing is, it's better to use this trick with OS X Font Tools instead of simply exporting with Glyphs, because Glyphs also edits the font's style name and postscript name, with makes xCode fail to find the font in some situations.Dismount
C
32

iOS 6 honors the font's lineGap property, while iOS 7 ignores it. So only custom fonts with a line gap of 0 will work correctly across both operating systems.

The solution is to make the lineGap 0 and make the ascender correspondingly larger. Per the answer above, one solution is to import and export from Glyphs. However, note that a future version of the app might fix this "bug".

A more robust solution is to edit the font yourself, per this post. Specifically,

  1. Install OS X Font Tools.
  2. Dump the font metrics to a file: ftxdumperfuser -t hhea -A d YOUR_FONT.ttf
  3. Open the dumped file in an editor.
  4. Edit the ascender property by adding the value of the lineGap property to it. For example, if the lineGap is 200 and the ascender is 750, make the ascender 950.
  5. Set the lineGap to 0.
  6. Merge the changes into the font: ftxdumperfuser -t hhea -A f YOUR_FONT.ttf

Once you do this, you might have to adjust your UI accordingly.

Charitycharivari answered 23/10, 2013 at 22:55 Comment(0)
H
6

For those running OS X El Capitan and coming to this thread, you might have noticed that the Apple Font Tool Suite is no longer compatible (at least for now).

But you can still perform the changes described by kolyuchiy and Joseph Lin with free font editing software FontForge.

Open the font with FontForge and select Element in the top menu, then go to Font Info > OS/2 > Metrics. There you want to edit the HHEad Line Gap and HHead Ascent Offset values.

Once you've done the necessary edits you can just export the font in File > Generate Fonts and select the right font format

Hertzog answered 11/11, 2015 at 15:59 Comment(0)
R
5
  1. Download and Install Apple's Font Tools here: https://developer.apple.com/downloads/index.action?q=font (the download link is in the bottom)
  2. Open the terminal and cd your way to where your font is
  3. Run this command: ftxdumperfuser -t hhea -A d MY_FONT_NAME.ttf
  4. Now you have an xml file with some of the font's properties, edit it in your text editor
  5. Search for the "lineGap" property and add 200 to its value
  6. Save the xml file
  7. Run this command: ftxdumperfuser -t hhea -A f MY_FONT_NAME.ttf
  8. Delete the xml file
  9. Try the configured font on iOS 6 and see if it looks better.
  10. If you need, you can go back to step 3 and add/subtract to the "lineGap" property. (I ended up adding 250 to my configuration)
Rainer answered 29/10, 2013 at 21:20 Comment(0)
R
4

We had the same issue with one of our custom fonts. We also "fixed" the problem by editing the font ascender property. However, we found that this created other problems and layout issues. For example dynamically setting cell height based on label height would blow up when using our ascender edited font.

What we ended up doing was changing the UIButton contentEdgetInsets property.

yourButton.contentEdgeInsets = UIEdgeInsetsMake(-10, 0, 0, 0);

Not sure which method is better, but just wanted to share another way to fix the problem.

Residence answered 22/4, 2013 at 18:7 Comment(2)
agreed. The ascender property fix isn't the ideal solutionPennyroyal
Hi Joshua, I just posted a method that might fix the issue you mentioned. In short, a few more properties need to be modified along with the ascender.Falsework
E
3

Thanks to the this answer I fixed my problem with Glyphs, but a little bit differently.

I opened my font with Glyphs (also works with Glyphs mini) and found this section there (this from Glyphs mini, to get there push i button in the right top corner):

enter image description here

Just delete all of this alignment zones (or some of them) and it will fix this problem. Worked perfectly for me.

Emissive answered 21/6, 2015 at 21:43 Comment(0)
S
2

Creating attributed text from your labels text was the fix for me. Heres an extension:

extension UILabel {
    /// You can call with or without param values; without will use default 2.0
    func setLineSpacing(lineSpacing: CGFloat = 2.0, lineHeightMultiple: CGFloat = 2.0) {
        guard let labelText = self.text else { return }
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = lineSpacing
        paragraphStyle.lineHeightMultiple = lineHeightMultiple
        let attributedString:NSMutableAttributedString
        if let labelattributedText = self.attributedText {
            attributedString = NSMutableAttributedString(attributedString: labelattributedText)
        } else {
            attributedString = NSMutableAttributedString(string: labelText)
        }
        // (Swift 4.2 and above) Line spacing attribute
        attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value:paragraphStyle, range:NSMakeRange(0, attributedString.length))
        self.attributedText = attributedString
    }
}

For my custom font I got the result I need from:

self.myLabel.setLineSpacing(lineSpacing: 1.2, lineHeightMultiple: 1.2)

This works by using the native provided NSMutableParagraphStyle() which contains line height and spacing properties (which are accessible as @IBOutlet properties in the Storyboard too if you are not programming your labels).

Standee answered 19/11, 2018 at 8:18 Comment(0)
V
1

Have you tried Core Text? I've had some success rendering custom fonts through Core Text, but I don't know if it would fit your situation.

Vouge answered 26/6, 2011 at 3:29 Comment(1)
I can confirm core text doesn't have this problem.Arleenarlen
D
1

I used https://github.com/fonttools/fonttools - very easy to use and free. In my case, the change of 'ascender'=1000 and 'lineGap'=0 in 'hhea' table did the trick.

Based on article from Trevor Harmon https://medium.com/@thetrevorharmon/how-to-use-apples-font-tools-to-tweak-a-font-a386600255ae

Digestive answered 5/1, 2020 at 9:56 Comment(0)
A
0

If your are having trouble with these command line utilities then try fontcreator on window. and change font assender from its setting menu.

Archaeology answered 27/7, 2012 at 6:15 Comment(0)
A
0

For anyone who are struggling to use ftxdumperfuser (kolyuchiy answer) on Mac OS Mojave because of command not found error:

  • Download the font tools package from Apple. Found them at https://developer.apple.com/download/more/?q=font, picked the one for XCode 11.
  • Mount the dmg file
  • Enter the disk image cd /Volumes/macOS\ Font\ Tools
  • Extract the package to a folder of your choosing: pkgutil --expand-full macOS\ Font\ Tools.pkg ~/font-tools
  • The CLI tools are now available in ~/font-tools/FontCommandLineTools.pkg/Payload, you may add the folder to your path (export PATH="$PATH:$HOME/font-tools/FontCommandLineTools.pkg/Payload"), or copy the utils to your bin folder.
Abbreviated answered 27/2, 2020 at 13:42 Comment(0)
A
-3

I had a similar issue with iconic "FontAwesome" font in my Sprite Kit game. Setting the SKLabelNode's SKLabelVerticalAlignmentMode property to .Center worked for me.

myLabel.verticalAlignmentMode = SKLabelVerticalAlignmentMode.Center

Just wanted to share in case somebody would be struggling with the same problem.

Apocynthion answered 20/7, 2015 at 5:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.