• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Making bezier paths out of text
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Making bezier paths out of text


  • Subject: Re: Making bezier paths out of text
  • From: Aki Inoue <email@hidden>
  • Date: Wed, 17 Sep 2003 09:25:12 -0700

Yes.

Aki

On 2003/09/17, at 1:54, John Stiles wrote:

So a workaround is to lockFocus on a valid NSView first?


On Tuesday, September 16, 2003, at 09:54 PM, Aki Inoue wrote:

There was a bug up until 10.2.x, -appendBezierPathWithGlyph:inFont: and -appendBezierPathWithGlyphs:count:inFont: were calling -[NSFont set].

So, if you don't have valid lockFocus'ed graphics context, you can get the error.

Aki

On 2003/09/16, at 16:38, John Stiles wrote:

I am working on an app that needs to convert text into a bezier path. It works about 99% of the time, but sometimes the paths just don't happen. No errors are reported to my code, but the bezier paths won't draw anything, and I get the following errors logged in the console.

Sep 16 16:28:55 MafiaHQ (myapp): kCGErrorFailure : CGContextSetTextMatrix: invalid context
Sep 16 16:28:55 MafiaHQ (myapp): kCGErrorFailure : CGContextSetFont: invalid context
Sep 16 16:28:55 MafiaHQ (myapp): kCGErrorFailure : CGContextSetFontSize: invalid context
Sep 16 16:28:55 MafiaHQ (myapp): kCGErrorFailure : CGContextGetFont: invalid context
Sep 16 16:28:55 MafiaHQ (myapp): kCGErrorFailure : CGContextGetFontSize: invalid context
Sep 16 16:28:55 MafiaHQ (myapp): kCGErrorFailure : CGContextGetTextMatrix: invalid context
(this pattern repeats once for every string I try to turn into bezier paths)

What could cause this? I wish I had a good reproducible case, but it's just sporadic. It does seem to happen more often after my app has been running for some time, but that could be coincidence.

Here's some of my code. I have butchered it up a bit to try to remove unfamiliar constructs and stuff from it, so it probably wouldn't compile out of the box, but it's mostly all there. Please let me know if anything seems out of place.

static void CreateBezierPath( NSBezierPath *bezier, NSString *string, float size, float *height, float *baseline )
{
// Make our text storage and layout.
NSTextStorage *storage = [[NSTextStorage alloc] initWithString:string];
[storage setFont:[NSFont boldSystemFontOfSize:size]];

// We don't hold on to the layout and container objects because the NSTextStorage
// object retains them for us.
NSLayoutManager *layout = [[[NSLayoutManager alloc] init] autorelease];
NSTextContainer *container = [[[NSTextContainer alloc] init] autorelease];
[layout addTextContainer:container];
[storage addLayoutManager:layout];

// Turn off padding in the container; otherwise we get extra space padding out each style run.
[container setLineFragmentPadding:0.0];

// Make a bezier path that will represent our text.
bezier = [[NSBezierPath alloc] init];
[bezier setCachesBezierPath:YES];
[bezier moveToPoint:NSMakePoint(0.0, 0.0)];

// Find each style run in the NSTextStorage.
int length = [storage length];
int position = 0;
while( position < length )
{
// Ask the string for a range of characters that all use one font.
NSRange range;
NSFont *layoutFont = [storage attribute:NSFontAttributeName atIndex:position effectiveRange:&range];
// Get the glyphs from the layout that correspond with the range.
AutoMemoryBlock glyphData( (range.length + 1) * sizeof(NSGlyph) ); // this is just a malloc that frees itself when descoped
int glyphCount = [layout getGlyphs:glyphData.Ptr<NSGlyph>() range:range];

// Create a bezier path for those glyphs using that font.
[bezier appendBezierPathWithGlyphs:glyphData.Ptr<NSGlyph>() count:glyphCount inFont:layoutFont];
[bezier setLineWidth:(size * 0.1f)];

// Keep track of how many glyphs have been consumed.
position += glyphCount;

// Get the baseline and height for this block of glyphs.
*baseline = max( *baseline, [layoutFont ascender] );
*height = max( *height, *baseline - [layoutFont descender] );
}

// Force the layout manager to layout the text, and then grab its width.
// (In the real code we save this, but in the sample code we just jettison it.
// Interestingly, this part seems to work just fine in any case.)
(void) [layout glyphRangeForTextContainer:container];
float width = [layout usedRectForTextContainer:container].size.width;

// Now that we have a bezier path, we no longer need the text layout objects.
[storage release];
}
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.

References: 
 >Re: Making bezier paths out of text (From: John Stiles <email@hidden>)

  • Prev by Date: Re: OpenGL performance (Cocoa)
  • Next by Date: Problem with NSTextCell subclass
  • Previous by thread: Re: Making bezier paths out of text
  • Next by thread: Re: Making bezier paths out of text
  • Index(es):
    • Date
    • Thread