Re: What rect does NSTextFieldCell use to draw its contents?
Re: What rect does NSTextFieldCell use to draw its contents?
- Subject: Re: What rect does NSTextFieldCell use to draw its contents?
- From: Kyle Sluder <email@hidden>
- Date: Fri, 14 Dec 2012 09:56:14 -0800
On Dec 14, 2012, at 2:42 AM, "email@hidden" <email@hidden> wrote:
>
> On 13 Dec 2012, at 23:17, Kyle Sluder <email@hidden> wrote:
>
>>
>> Since I'm comparing the string-drawing methods to NSTextFieldCell
>> drawing, according to this documentation there should be no difference.
> In my test case I compared the cells rendering with an NSTextField configured as a label.
>
> @implementation MyTextFieldCell
>
> - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
> NSStringDrawingOptions options = 0;
> if (self.truncatesLastVisibleLine)
> options |= NSStringDrawingTruncatesLastVisibleLine;
> if (!self.usesSingleLineMode)
> options |= NSStringDrawingUsesLineFragmentOrigin;
>
> NSAttributedString *attString = [[NSAttributedString alloc] initWithString:self.stringValue];
> [attString drawWithRect:[self titleRectForBounds:cellFrame] options:options];
> }
>
> @end
>
> I tried the following uber simple implementation above and it doesn't produce the same rendering as a standard text cell.
> The custom implementation is a couple of pixels offset to the left plus the font weight and kerning is slightly different.
Well, you're not using the same attributes, so of course it's not going to be the same. I went so far as to get the exact attributes the text field uses by calling -_textAttributes, in the hope that it was a line fragment padding issue. Still no dice.
>
> So the implementation used by NSTextFieldCell obviously isn't the same as this.
> The cell is free of course to offset the text frame as it sees fit prior to actual text rendering.
> e.g.: when drawing complex cells with images etc it is necessary to introduce offsets between the rendered elements.
Yes, that's the offset frame I'm trying to figure out.
>
> The docs for drawInteriorWithFrame:inView: say:
>
> Text-type NSCell objects display their contents in a rectangle slightly inset from cellFrame using a global NSText object.
>
> Is that offset accessible via the API or related to titleRectForBounds:?
According to my understanding of the API, -titleRectForBounds: should be returning this rect, but clearly NSTextFieldCell is insetting this rect further.
But NSTextFieldCell does its own drawing anyway. It doesn't call -[NSCell drawInteriorWithFrame:inView:], so it doesn't go through the "text-type NSCell" drawing path.
>
> The docs for titleRectForBounds: say:
>
> If the receiver is a text-type cell, this method resizes the drawing rectangle for the title (theRect) inward by a small offset to accommodate the cell border. If the receiver is not a text-type cell, the method does nothing.
>
> But surely the cellFrame received by drawInteriorWithFrame:inView: has already accounted for the cell border, or is this another interior border?
My text field is borderless. I can confirm that -drawInteriorWithFrame receives the same rect as -drawWithFrame:inView:.
>
> So I think this might be an implementation guessing game.
I have a disassembler; I can do better than guess. :) I was just hoping there was some aspect of the documentation I had overlooked.
>
> If the rendering issue is comparative (i.e.: the custom render looks bad compared to the default in say a table view) then a solution might be to use the custom implementation everywhere.
Thankfully appearance isn't an issue; my custom text field cell will be used for all instances in the same area. My chief concern is what NSTextField will return for -layoutRectForFrame: and how it will differ from my actual drawing metrics, which is why I'm trying to replicate NSTextFieldCell's drawing precisely.
--Kyle Sluder
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden