[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