开发者

Redraw NSBezierPath multiple times, with scaling?

I am currently writing many chunks of text on an NSView using the NSString helper method ... however it is very slow to write a large amount of in many cases repeated text. I am trying to re-write the code so that the text is converted to NSBezierPath's that are generated once, then drawn many times. The following will draw text at the bottom of the screen.

I am still trying to read through the apple documentation to understand how this works, but in the mean time I wonder if there is an easy way to alter this code to re-draw the path in multiple locations?

// Write a path to the view
NSBezierPath* path = [self bezierPathFromText: @"Hello world!" maxWidth: width];
[[NSColor 开发者_JAVA百科grayColor] setFill];
[path fill];

Here is the method that writes some text into a path:

-(NSBezierPath*) bezierPathFromText: (NSString*) text maxWidth: (float) maxWidth {

// Create a container describing the shape of the text area,
// for testing done use the whole width of the NSView.
NSTextContainer* container = [[NSTextContainer alloc] initWithContainerSize:NSMakeSize(maxWidth - maxWidth/4, 60)];

// Create a storage object to hold an attributed version of the string to display
NSFont* font = [NSFont fontWithName:@"Helvetica" size: 26];
NSDictionary* attr = [NSDictionary dictionaryWithObjectsAndKeys: font, NSFontAttributeName, nil];
NSTextStorage* storage = [[NSTextStorage alloc] initWithString: text attributes: attr];

// Create a layout manager responsible for writing the text to the NSView
NSLayoutManager* layoutManger = [[NSLayoutManager alloc] init];
[layoutManger addTextContainer: container];
[layoutManger setTextStorage: storage];

NSRange glyphRange = [layoutManger glyphRangeForTextContainer: container];
NSGlyph glyphArray[glyphRange.length];
NSUInteger glyphCount = [layoutManger getGlyphs:glyphArray range:glyphRange];

NSBezierPath* path = [[NSBezierPath alloc] init];
//NSBezierPath *path = [NSBezierPath bezierPathWithRect:NSMakeRect(0, 0, 30, 30)];
[path moveToPoint: NSMakePoint(0, 7)]; 
[path appendBezierPathWithGlyphs:glyphArray count: glyphCount inFont:font];

// Deallocate unused objects
[layoutManger release];
[storage release];
[container release];

return [path autorelease];
}

Edit: I am attempting to optimise an application that outputs to screen, a sequence of large amounts text such as a sequence of 10,000 numbers. Each number has markings around it and/or differing amounts of space between them, and some numbers have dots and/or lines above, below or between them. Its like the example at the top of page two of this document but with much much more output.


You could start by removing the line:

[path moveToPoint: NSMakePoint(0, 7)];

so that your path isn't tied to a particular location in the view. With that done, you can call your method to get the path, move to a point, stroke the path, move to another point, stroke the path, and so on. If you want to move from the starting point within the path description, use -relativeMoveToPoint:.


It appears this might do the trick, however I am not sure if it is the best way to do it?

// Create the path
NSBezierPath* path = [self bezierPathFromText: @"Fish are fun to watch in a fish tank, but not fun to eat, or something like that." maxWidth: width];

// Draw a copy of it at a transformed (moved) location
NSAffineTransform* transform = [[NSAffineTransform alloc] init];
[transform translateXBy: 10 yBy: 10];
NSBezierPath* path2 = [path copy];
[path2 transformUsingAffineTransform: transform];
[[NSColor greenColor] setFill];
[path2 fill];
[path2 release];
[transform release];
[path2 release];

// Draw another copy of it at a transformed (moved) location
transform = [[NSAffineTransform alloc] init];
[transform translateXBy: 10 yBy: 40];
path2 = [path copy];
[path2 transformUsingAffineTransform: transform];
[[NSColor greenColor] setFill];
[path2 fill];
[path2 release];
[transform release];
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜