0

I've been looking for a solution for this one all day.

I have 4 NSTextFields (actually subclassed for a few custom operations), which all share the same X position.

The problem is, some have different styles (light, regular, bold) and might have different sizes.

What happens is that, even though the X origin is the same, the 1st letter always has a bit of (consistently different) left margins.

Please see pic: https://dl.dropbox.com/u/1977230/Screen%20Shot%202012-12-11%20at%2017.55.58.png

I want to make sure that all lines start exactly at the same point, say 100px from the left.

Any idea how to override that weird padding?

Cheers

Andre
  • 4,417
  • 8
  • 32
  • 37
  • I should add that the grey blocks are the NSTextField backgrounds, which are correctly aligned, as you can see. – Andre Dec 11 '12 at 18:00
  • this [post](http://stackoverflow.com/a/2825508/1354100) might help maybe? Or i wonder if trying to use only Fixed Width Fonts would work – Bejmax Dec 11 '12 at 19:24
  • Fixed width fonts would work, but I need to use the brand's font :/ That post doesn't really help, I think, since I only need the 1st letter to be aligned to the left. The next ones are fine, in relation to each other. However, that 1st letter might be random, so I never know what spacing it'll have beforehand :( – Andre Dec 12 '12 at 14:42
  • Could you adjust the position of the view based on how much leading space there is in the first character? so not exactly as the post i linked above but similar, good luck. – Bejmax Dec 12 '12 at 15:32

3 Answers3

6

The margin you're talking about I'm pretty sure is the lineFragmentPadding on the NSTextContainer that is used by the NSTextField.

See the NSTextContainer reference:

http://developer.apple.com/library/Mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSTextContainer_Class/Reference/Reference.html

And here's a page from the tutorial on Text Layout:

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/TextLayout/Concepts/CalcTextLayout.html

It states in that article:

The typesetter makes one final adjustment when it actually fits text into the rectangle. This adjustment is a small amount fixed by the NSTextContainer object, called the line fragment padding, which defines the portion on each end of the line fragment rectangle left blank. Text is inset within the line fragment rectangle by this amount (the rectangle itself is unaffected). Padding allows for small-scale adjustment of the text container’s region at the edges and around any holes and keeps text from directly abutting any other graphics displayed near the region. You can change the padding from its default value with the setLineFragmentPadding: method. Note that line fragment padding isn’t a suitable means for expressing margins; you should set the NSTextView object’s position and size for document margins or the paragraph margin attributes for text margins.

Unfortunately, it looks like NSTextField's NSTextContainer and NSLayoutManager are private and inaccessible, but it appears they are accessible in an NSTextView:

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSTextView_Class/Reference/Reference.html#//apple_ref/occ/cl/NSTextView

So that may be the class you need to subclass if you want to have minute control over this kind of functionality.

eyebrowsoffire
  • 957
  • 7
  • 15
2

Have you looked into CoreText? I think it may provide the facilities to do what you're looking for. From the docs...

The Core Text layout engine is designed specifically to make simple text layout operations easy to do and to avoid side effects.

You are able to access "font metrics," which enable you to (from the docs)...

For every font, glyph designers provide a set of measurements, called metrics, which describe the spacing around each glyph in the font. The typesetter uses these metrics to determine glyph placement. Font metrics are parameters such as ascent, descent, leading, cap height, x-height, and so on.

EDIT: It just may be that NSTextField was not designed for what you are trying to do. NSTextField does custom layout apart from a NSLayoutManager. You may need to upgrade to a NSTextView, which always has a dedicated NSLayoutManager attached. Apple has some example projects you could search for using NSLayoutManager and NSTextView.

Bejmax
  • 945
  • 7
  • 16
  • I have not looked into it. Will have a go now! Thanks – Andre Dec 13 '12 at 12:41
  • Freaking hell. CoreText can be really complicated for someone who had never heard of it before. Will add bounty to the OP to see if I can get an example of how to do it. Thanks for your help – Andre Dec 19 '12 at 16:10
1

If you're using NSTextField to draw simple static text, take a look at AppKit additions to NSString. Use sizeWithAttributes: to get size of the "text" image. Then use the size to calculate rects for drawing. Finally use one of draw methods to actually draw text. Don't forget to "round" result of sizeWithAttributes! It's not pixel aligned.

But if you need to draw something more complex than simple label, use Core Text. You can find very good example of how to use it in twui source code.

Kentzo
  • 3,881
  • 29
  • 54