Re: Making bezier paths out of text
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.