Re: NSShadowAttributeName doesn't scale
Re: NSShadowAttributeName doesn't scale
- Subject: Re: NSShadowAttributeName doesn't scale
- From: Leonardo <email@hidden>
- Date: Tue, 03 Dec 2013 01:59:05 +0100
- Thread-topic: NSShadowAttributeName doesn't scale
Hi Graham,
your solution looks great. But I can¹t succeed at overriding the shadow¹s
³set² method.
I have properly subclassed NSShadow as MyShadow. So I assign myShadow to the
text this way
MyShadow *shad = [[MyShadow alloc] init];
[shad setShadowOffset:NSMakeSize(x, y)];
[self.textStorage removeAttribute:NSShadowAttributeName range:range];
[self.textStorage addAttribute:NSShadowAttributeName value:shad
range:range];
[shad release];
In the MYShadow class I do
- (void)set
{
NSLog(@"SBShadow set");
NSSize offset = self.shadowOffset;
offset.width *= scaleX;
offset.height *= scaleY;
self.shadowOffset = offset;
[super set];
}
But I never get this Log when I add the shadow to the text (the first
display!), nor when I scale the NSTextView nor when I type a new text within
the shadowed text, nor when I move the textView over the page, nor when I
call [textView display] nor [textView setNeedsDisplay:YES]; It seems that
rendering the text doesn¹t call the shadow¹s set method.
------
I would like to tell you the solution I have found, not so fine but it
works.
I subclassed the NSShadow as MyShadow and defined a method¹s variable:
NSSize mAbsOffset;
I assign to this variable the shadow offset when the scale factor is 1 and I
never change it.
I added an observer to the textView when the scale factor changes, which
calls my method ZoomTextShadows.
Therein I scan the textStorage looking for the NSShadowAttributeName then I
replace the shadows with new shadows with
newShad.shadowOffset = oldShad.mAbsOffset * currentScaleFactor;
It works well and fast. But I guess your solution is better even because I
don¹t need to store the mAbsScaleOffset, which I lose when pasting the text
to other apps. And here we should begin a new conversation about pasting
shadows at different scales...
Regards
-- Leonardo
Da: Graham Cox <email@hidden>
Data: Sat, 30 Nov 2013 21:40:04 +0100
A: Leonardo <email@hidden>
Cc: Cocoa-dev <email@hidden>
Oggetto: Re: NSShadowAttributeName doesn't scale
On 30 Nov 2013, at 2:54 pm, Leonardo <email@hidden> wrote:
> In facts, the NSShadow manual reports:
> "rotations, translations and other transformations of the current
> transformation matrix (the CTM) do not affect the resulting shadow."
>
> So, how to modify the NSShadowAttributeName accordingly to the view scale?
> I guess I have to modify some context's parameter in the NSTextView
> drawRect: method. But I don't know how.
That¹s right: shadows don¹t scale. It¹s jolly annoying, but there is a way
to solve it. One word of caution though, and possibly an explanation for why
Apple decided to let shadows bypass the CTM - when shadows get large, they
get very, very slow indeed. So much so that they will basically kill your
drawing performance. Even one enlarged shadow can bring everything to a
crashing halt.
So, with that out of the way, here¹s the way I¹ve solved this.
At the point of drawing, grab the current CTM, work out how much it *should*
be scaling things, then multiply all the shadow variables by that amount,
set the new shadow, and draw.
CGAffineTransform ctm = CGContextGetCTM( context );
CGSize unit = CGSizeApplyAffineTransform( CGSizeMake( 1, 1 ), ctm );
Here, unit' ends up with values representing how much things are being
scaled by. You then grab the original shadow parameters, multiply them by
this to make a new shadow, set it, and draw.
You can do this for shadows applied to text by subclassing NSShadow and
overriding the -set method, then substitute the scaled shadow and set that.
You might want to consider setting limits on what scale factors this will be
allowed up to, or whether in some cases a quick-and-dirty¹ shadow (like
drawing a solid drop shadow temporarily when doing live resizes, scrolling
or zooming, replaced by a soft shadow when things settle for a second). If
you don¹t you will quickly see the sorts of performance tragedies I¹m
talking about.
Graham
_______________________________________________
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