I'm trying to draw a stroke of Bezier Curve with linear gradient going from red to green. What I do at the moment is:
NSBezierPath* path = [NSBezierPath bezierPath];
[path setLineWidth: 1];
NSPoint startPoint = { 10, 100 };
NSPoint endPoint = { 590, 500 };
int r1 = arc4random() % 1000;
int r2 = arc4random() % 1000;
NSPoint cp1 = { 700, -500 + r1 };
NSPoint cp2 = { -500 + r2, 700 };
[path moveToPoint: startPoint];
[path curveToPoint: endPoint
controlPoint1: cp1
controlPoint2: cp2];
if (curves.count == 50) {
[curves removeObjectAtIndex:0];
}
[curves addObject:path];
int i = 0;
for (NSBezierPath * p in curves) {
[[redColors objectAtIndex:i++] set];
[p stroke];
}
And this works great, but when I convert NSBezierPath path
to CGPathRef myPath = [path quartzPath]
and iterate over 'CGPathRef' instead of 'NSBezierPath':
CGPathRef myPath = [path quartzPath];
if (curves.count == size) {
[paths removeObjectAtIndex:0];
}
[paths addObject:myPath];
CGContextRef c = [[NSGraphicsContext currentContext]graphicsPort];
for (int i = 0; i < paths.count; i++) {
[self drawPath:c :[paths objectAtIndex:i]:i];
}
My performance drops from about 30 FPS to 5 FPS!
Here is my code for drawPath:
-(void) drawPath:(CGContextRef) c: (CGPathRef) myPath: (int) i {
CGContextSaveGState(c);
CGContextAddPath(c, myPath);
CGContextReplacePathWithStrokedPath(c);
CGContextClip(c);
// Draw a linear gradient from top to bottom
CGContextDrawLinearGradient(c, cfGradients[i], start, end, 0);
CGContextRestoreGState(c);
}
开发者_如何学C
redColors
and cfGradients
are arrays storing elements with alpha from 0-1/0-255, so they don't need to be recreated at each iteration.
This performance is even much worse than in Java. Surely there must be a way to draw a stroke more efficiently without all this transitions from NSBezierPath
to CGPathRef
, etc.
Please help.
精彩评论