[Drawkit] Another text issue in non-flipped drawings

Allan Daly allandaly at me.com
Thu Jun 4 07:58:38 PDT 2009


Graham --> Ahh, I get it now.

Antonio --> Thanks for the suggestion -- it looks promising. I'll give  
it a whirl.

-Allan


On Jun 4, 2009, at 7:06 AM, António Nunes wrote:

> 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!
>
> 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



More information about the Drawkit mailing list