Text Outlines

I have shape objects that contain text. I also have a routine to convert whatever text in in that shape to outline text. Originally, this was based on code in the Speedometer sample code. Unfortunately, the routines used in this process are now deprecated and I have been trying to update it, and it is not working so well.


The main process uses a subclass of NSLayout manager and used to implement:

- (void)showPackedGlyphs:(char *)glyphs length:(unsigned)glyphLen

glyphRange:(NSRange)glyphRange atPoint:(NSPoint)point font:(NSFont *)font

color:(NSColor *)color printingAdjustment:(NSSize)printingAdjustment


Now, I'm using:

- (void)showCGGlyphs:(const CGGlyph *)glyphs positions:(const NSPoint *)positions count:(NSUInteger)glyphCount font:(NSFont *)font matrix:(NSAffineTransform *)textMatrix attributes:(NSDictionary<NSString *, id> *)attributes inContext:(NSGraphicsContext *)graphicsContext


So far, I'va managed to get it working for odd shapes and multi-line styled text. One problem -- In the accumulated Bezier, each line of outline text is in the right order and position, but upside down. Obviously, this is going to require a transform somewhere, but so far all my attempts at such have been failures.


Anyone had success with this?

As usual, after a couple of days of frustation and finally posting it, I think I've cracked it. The trick was to evaluate the individual glyphs so you can flip them before accumulating.


// This is the un-deprecated method to use.

- (void)showCGGlyphs:(const CGGlyph *)glyphs positions:(const NSPoint *)positions count:(NSUInteger)glyphCount font:(NSFont *)font matrix:(NSAffineTransform *)textMatrix attributes:(NSDictionary<NSString *, id> *)attributes inContext:(NSGraphicsContext *)graphicsContext {


NSUInteger i;

for(i = 0; i < glyphCount; i++) {

NSPoint pos = positions[i];


// Get the individual glyph Bezier positoned at origin.

NSBezierPath *glyphPath = [NSBezierPath bezierPath];

// This "moveTo" is required, or you will throw an exception.

[glyphPath moveToPoint:NSZeroPoint];

[glyphPath appendBezierPathWithGlyph:glyphs[i] inFont:font];


// Flip it. Then position it.

NSAffineTransform *xfrm = [NSAffineTransform transform];

[xfrm scaleXBy:1.0 yBy:-1.0];

[xfrm translateXBy:pos.x yBy:-pos.y];

glyphPath = [xfrm transformBezierPath:glyphPath];


// Accumulate.

[self.theBezierPath appendBezierPath:glyphPath];

}

}


Another important point. When forcing the layout, use the older NSImage initWithSize, focus, unfocus, etc.. If you try to use the newer method with the completion handler, it will never draw and won't work.

Text Outlines
 
 
Q