Skip navigation.
 
mlRe: Finding the height of a piece of text
FROM : Aki Inoue
DATE : Mon Nov 26 22:04:27 2007

Hmm, since you're using the same layout manager instance for measuring 
and rendering, it doesn't appear to be one of common pitfall cases.

Maybe you might want to add logging to your -drawRect: and -
desiredWidthForHeight: method so that the desired width, bounds width, 
and contained width all agree.

Aki

On 2007/11/26, at 11:15, Vincent Coetzee wrote:

> Dear Aki,
>
> When I say the height returned is too small, I mean that if I render 
> the text in that font, in an NSRect whose width is the width I used 
> to measure the height with, and whose height is the returned height, 
> then the last line of text is invariably not visible. In other 
> words, the returned height seems to be approximately 1 line too 
> small. I am not sure this is clear. As far as rendering goes, I have 
> tried rendering by just about every means, and they all render 
> incorrectly i.e. the area they render in is too small. I have set 
> the typesetter behavior to no avail, I attach my revised code (for 
> both measuring and rendering) in which the height is still 
> incorrect. Please let me know if this answers the questions or if 
> you need more info...
>     
> My class FixedWidthTextItem is a subclass of NSView. The unshown 
> objects first set the desired width for the FixedWidthTextItem
> by means of the accessor FixedWidthTextItem::setDesiredWidth, 
> thereafter they measure the height of the view using
> FixedWidthTextItem::desiredHeightForWidth and then they set the 
> frame of the view with an NSRect that is calculated to be 
> someX,someY,desiredWidth,desiredHeightForWidth:desiredWidth.
> The view is then asked to render itself by the normal 
> setNeedsDisplay: YES mechanism.
>
> e.g.
>
> desiredWidth <- 200
> textItem <- FixedWidthTextItem new
> [textItem setDesiredWidth: desiredWidth]
> height <- [textItem desiredHeightForWidth: desiredWidth]
> [textItem setFrame: NSMakeRect(someX,someY,desiredWidth,height)]
> [textItem setNeedsDisplay: YES]
>
>
> @implementation FixedWidthTextItem
>
>
> - (void) initialize
>     {
>     [super initialize];
>     theDesiredWidth = 10.0f;
>     theTextStorage  = [[NSTextStorage alloc] initWithString: @""];
>     theTextContainer = [[NSTextContainer alloc] initWithContainerSize: 
> NSMakeSize(theDesiredWidth, FLT_MAX)];
>     theLayoutManager = [[NSLayoutManager alloc] init];
>     [theLayoutManager setTypesetter: [NSTypesetter 
> sharedSystemTypesetterForBehavior: 
> NSTypesetterBehavior_10_2_WithCompatibility]];
>     [theLayoutManager setHyphenationFactor: 0.5];
>     [theLayoutManager addTextContainer: theTextContainer];
>     [theTextStorage addLayoutManager: theLayoutManager];
>     [theTextContainer setLineFragmentPadding:2.0];
>     //[theLayoutManager setShowsControlCharacters: YES];
>     //[theLayoutManager setShowsInvisibleCharacters: YES];
>     }
>     
> - (void) update: (NSString*) aspect with: (id) object from: (id) 
> sender
>     {
>     NSString*    value;
>     
>     if (sender == theStringHolder && [aspect isEqualToString: @"value"])
>         {
>         value = [theStringHolder value];
>         NSAssert(value,@"stringHolder value == nil in update");
>         [theTextStorage replaceCharactersInRange: NSMakeRange(0,
> [theTextStorage length]) withString: value];
>         [self requestLayout];
>         }
>     }
>     
> - (void) drawRect: (NSRect) rect
>     {
>     [theTextContainer setContainerSize: [self bounds].size];
>     [theLayoutManager glyphRangeForTextContainer: theTextContainer];
>     [theLayoutManager drawGlyphsForGlyphRange: [theLayoutManager 
> glyphRangeForTextContainer: theTextContainer] atPoint: [self 
> bounds].origin];
>     }
>     
> - (void) setStringValue: (NSString*) string
>     {
>     [theTextStorage replaceCharactersInRange: NSMakeRange(0,
> [theTextStorage length]) withString: string];
>     }
>     
> - (float) desiredWidth
>     {
>     return(theDesiredWidth);
>     }
>     
> - (void) setDesiredWidth: (float) width
>     {
>     theDesiredWidth = width;
>     }
>     
> - (void) setStyleValues
>     {
>     NSFont*        font;
>     NSColor*    color;
>     
>     font = [[self styleValueForKey: StyleTextFont] value];
>     NSAssert(font,@"font is nil in FixedWidthTextItem::setStyleValues");
>     [theTextStorage setFont: font];
>     color = [[self styleValueForKey: StyleTextColor] value];
>     NSAssert(color,@"color is nil in 
> FixedWidthTextItem::setStyleValues");
>     [theTextStorage setForegroundColor: color];
>     }
>     
> - (float) desiredHeightForWidth: (float) width
>     {
>     [self setStyleValues];
>     [theTextContainer setContainerSize: NSMakeSize(width,FLT_MAX)];
>     [theLayoutManager glyphRangeForTextContainer: theTextContainer];
>     return([theLayoutManager usedRectForTextContainer: 
> theTextContainer].size.height);
>     }
>
>
> On 26 Nov 2007, at Monday 26/11/200720:11 , Aki Inoue wrote:

>> Vincent,
>>
>> One thing unclear from your description is how the height returned 
>> from the code snippet is incorrect.  You mentioned the height is 
>> too small.
>> We need to know how it's small compared to what.  Are you measuring 
>> using the layout manager and rendering with something else ?
>>
>> If you're using either NSStringDrawing or NSCell, as Steve 
>> mentioned, it's most likely typesetter behavior mismatch.
>>
>> Thanks,
>>
>> Aki
>>
>> On 2007/11/23, at 1:16, Vincent Coetzee wrote:
>>

>>> Dear List
>>>
>>> I tried your suggestions, alas, it makes no difference ?
>>>
>>> HELP !
>>>
>>> Vincent
>>>
>>> On 23 Nov 2007, at Friday 23/11/200708:39 , Nygard Steve wrote:
>>>

>>>>
>>>> On Nov 22, 2007, at 5:56 PM, Vincent Coetzee wrote:
>>>>

>>>>> I however always end up with the same problem, in that the 
>>>>> height that I calculate for my text (as per the code in the 
>>>>> "Text Layout Programming Guide") is always too small (by about 
>>>>> ~1 line height) . Does anyone have a working solution to this 
>>>>> problem or a more elegant method of solving it ?

>>>>
>>>> To calculate a height that matches an NSTextFieldCell, the line 
>>>> fragment padding should be 2 (or 4 for a center alignment).  And 
>>>> the layout manager's typesetter behavior should be 
>>>> NSTypesetterBehavior_10_2_WithCompatibility.
>>>>
>>>> --
>>>> Steve
>>>>
>>>> _______________________________________________
>>>>
>>>> Cocoa-dev mailing list (<email_removed>)
>>>>
>>>> Please do not post admin requests or moderator comments to the 
>>>> list.
>>>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>>>>
>>>> Help/Unsubscribe/Update your Subscription:
>>>> http://lists.apple.com/mailman/options/cocoa-dev/vincent.<email_removed>
>>>>
>>>> This email sent to vincent.<email_removed>

>>>
>>> _______________________________________________
>>>
>>> Cocoa-dev mailing list (<email_removed>)
>>>
>>> Please do not post admin requests or moderator comments to the list.
>>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>>>
>>> Help/Unsubscribe/Update your Subscription:
>>> http://lists.apple.com/mailman/options/cocoa-dev/<email_removed>
>>>
>>> This email sent to <email_removed>

>>

Related mailsAuthorDate
mlFinding the height of a piece of text Vincent Coetzee Nov 23, 01:56
mlRe: Finding the height of a piece of text Nygard Steve Nov 23, 07:39
mlRe: Finding the height of a piece of text Vincent Coetzee Nov 23, 10:16
mlRe: Finding the height of a piece of text Jerry Krinock Nov 23, 16:00
mlRe: Finding the height of a piece of text Aki Inoue Nov 26, 19:11
mlRe: Finding the height of a piece of text Aki Inoue Nov 26, 22:04