[Drawkit] Another text issue in non-flipped drawings

António Nunes toniospamfree at mac.com
Thu Jun 4 07:06:47 PDT 2009


On 4 Jun 2009, at 13:56, Graham Cox wrote:

> This is exactly the problem with NSLayoutManager. It assumes a  
> flipped context and lays out lines in what it thinks is top-down  
> order. In an un-flipped context that ends up as bottom-up order. The  
> glyphs themselves end up right-way up because the actual rendering  
> correctly takes into account whether the context is flipped or not.
>
> As far as I can see there's no simple way to fix this without  
> subclassing, but I think the subclass should be fairly  
> straightforward. All it needs to do is to temporarily flip the  
> context (using a suitable transform) just before performing layout  
> so that it thinks it's drawing into a top-down context as usual. No  
> doubt there will be a few unexpected problems along the way - I keep  
> finding them with text!

Hiya,

I struggled with this in my code quite while ago, and ended up finding  
a solution. I haven't followed this thread too closely, but it just  
occurred to me my solution might be useufl to you. In a drawRect  
method for a text object in my software I use the following code:

		if (glyphRange.length > 0) {
			// To prevent the lines being drawn from the bottom up we need to  
flip the current context
			NSGraphicsContext *savedContext = [NSGraphicsContext currentContext];
			NSGraphicsContext *nsgc = [NSGraphicsContext  
graphicsContextWithGraphicsPort:[savedContext graphicsPort]  
flipped:YES];
			[NSGraphicsContext setCurrentContext:nsgc];
			NSAffineTransform *transform = [NSAffineTransform transform];
			[self rotateTransform:transform];
			[transform scaleXBy:1.0 yBy:-1.0];  // invert the y-axis and
			[transform translateXBy:0 yBy:-(NSMinY(bounds) +  
NSMaxY(bounds))]; // 'invert' the drawing origin
			[transform concat];
			
			[lm drawBackgroundForGlyphRange:glyphRange atPoint:bounds.origin];
			[lm drawGlyphsForGlyphRange:glyphRange atPoint:bounds.origin];
			
			[NSGraphicsContext setCurrentContext:savedContext];
		}

So, you need to dive down to Quartz temporarily: First flip the  
context, then perform your drawing, then restore the saved context (or  
flip back to original orientation). You can ignore the rotation stuff,  
but the y-axis inversion and drawing origin inversion are critical.  
(If I remember correctly. I haven't looked at this in ages upon ages.  
Anyway, this should give you the technique. Adjust the details to your  
own context.)

Hope this helps,
António
SintraWorks

--------------------------------------------
I try to take one day at a time, but sometimes, several days attack me  
all at once!
--------------------------------------------


----------------------------------------------------
Disapprove of sin but not of the sinner
----------------------------------------------------




More information about the Drawkit mailing list