mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-07 16:54:52 +00:00
Rewrite recursive block using stack and while loop.
This commit is contained in:
@@ -135,12 +135,12 @@ void GetBezierElements(void *info, const CGPathElement *element)
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void (^)(CGFloat *, NSInteger *, NSMutableArray *, NSMutableArray *, BOOL *)) getTextProperties{
|
- (void (^)(CGFloat *, NSInteger *, NSMutableArray *, NSMutableArray *, BOOL *)) getTextProperties{
|
||||||
return ^(CGFloat *lengthP, NSInteger *lineCountP, NSMutableArray * lengths, NSMutableArray * lines, BOOL *isClosedP) {
|
return ^(CGFloat *lengthP, NSInteger *lineCountP, NSMutableArray * lengths, NSMutableArray * lines, BOOL *isClosedP) {
|
||||||
__block CGPoint origin = CGPointMake (0.0, 0.0);
|
CGPoint origin = CGPointMake (0.0, 0.0);
|
||||||
__block CGPoint last = CGPointMake (0.0, 0.0);
|
CGPoint last = CGPointMake (0.0, 0.0);
|
||||||
__block NSInteger lineCount = 0;
|
NSInteger lineCount = 0;
|
||||||
__block CGFloat length = 0;
|
CGFloat length = 0;
|
||||||
__block BOOL isClosed = NO;
|
BOOL isClosed = NO;
|
||||||
NSArray * elements = self.elements;
|
NSArray * elements = self.elements;
|
||||||
for (BezierElement *element in elements) {
|
for (BezierElement *element in elements) {
|
||||||
switch (element.elementType)
|
switch (element.elementType)
|
||||||
@@ -175,34 +175,36 @@ void GetBezierElements(void *info, const CGPathElement *element)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ok, this is the bezier for our current element
|
// this is the bezier for our current element
|
||||||
CGPoint bezier[4] = { last, ctrl1, ctrl2, curveTo };
|
CGPoint bezier[4] = { last, ctrl1, ctrl2, curveTo };
|
||||||
|
NSValue *arr = [NSValue valueWithBytes:&bezier objCType:@encode(CGPoint[4])];
|
||||||
|
NSMutableArray *curves = [NSMutableArray arrayWithObjects:arr, nil];
|
||||||
|
|
||||||
|
NSInteger count = 1;
|
||||||
|
while (count-- > 0) {
|
||||||
|
CGPoint bez[4];
|
||||||
|
[curves[count] getValue:&bez];
|
||||||
|
[curves removeLastObject];
|
||||||
|
|
||||||
// define our recursive function that will
|
|
||||||
// help us split the curve up as needed
|
|
||||||
__weak void (^ __block weakFlattenCurve)(CGPoint bez[4]);
|
|
||||||
void (^ __block flattenCurve)(CGPoint bez[4]) = ^(CGPoint bez[4]){
|
|
||||||
// calculate the error rate of the curve vs
|
// calculate the error rate of the curve vs
|
||||||
// a line segement between the start and end points
|
// a line segement between the start and end points
|
||||||
CGPoint onCurve = bezierPointAtT(bez, .5);
|
CGPoint onCurve = bezierPointAtT(bez, .5);
|
||||||
CGPoint next = bez[3];
|
CGPoint next = bez[3];
|
||||||
CGFloat error = distanceOfPointToLine(onCurve, last, next);
|
CGFloat error = distanceOfPointToLine(onCurve, last, next);
|
||||||
|
|
||||||
// if the error is less than our accepted level of error,
|
// if the error is less than our accepted level of error
|
||||||
// then add a line,
|
// then add a line, else, split the curve in half
|
||||||
// otherwise, split the curve in half and recur
|
|
||||||
if (error <= idealFlatness) {
|
if (error <= idealFlatness) {
|
||||||
addLine(&last, &next, lines, &length, lengths);
|
addLine(&last, &next, lines, &length, lengths);
|
||||||
lineCount++;
|
lineCount++;
|
||||||
} else {
|
} else {
|
||||||
CGPoint bez1[4], bez2[4];
|
CGPoint bez1[4], bez2[4];
|
||||||
subdivideBezierAtT(bez, bez1, bez2, .5);
|
subdivideBezierAtT(bez, bez1, bez2, .5);
|
||||||
weakFlattenCurve(bez1);
|
[curves addObject:[NSValue valueWithBytes:&bez2 objCType:@encode(CGPoint[4])]];
|
||||||
weakFlattenCurve(bez2);
|
[curves addObject:[NSValue valueWithBytes:&bez1 objCType:@encode(CGPoint[4])]];
|
||||||
|
count += 2;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
weakFlattenCurve = flattenCurve;
|
|
||||||
weakFlattenCurve(bezier);
|
|
||||||
last = curveTo;
|
last = curveTo;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user