Commits

martinwinter committed fd9b3aa

Add logging for CGPath. Fix bug in element-at-index function. CGPath-based version now works fine on OS X.

Comments (0)

Files changed (7)

VectorBoolean.xcodeproj/project.xcworkspace/xcuserdata/martinwinter.xcuserdatad/UserInterfaceState.xcuserstate

Binary file removed.

VectorBoolean.xcodeproj/xcuserdata/martinwinter.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist

-<?xml version="1.0" encoding="UTF-8"?>
-<Bucket
-   type = "1"
-   version = "1.0">
-   <FileBreakpoints>
-      <FileBreakpoint
-         shouldBeEnabled = "Yes"
-         ignoreCount = "0"
-         continueAfterRunningActions = "No"
-         filePath = "VectorBoolean/CGPath_Boolean.m"
-         timestampString = "365636402.235607"
-         startingColumnNumber = "9223372036854775807"
-         endingColumnNumber = "9223372036854775807"
-         startingLineNumber = "15"
-         endingLineNumber = "15"
-         landmarkName = "CGPath_FBCreateUnion()"
-         landmarkType = "7">
-      </FileBreakpoint>
-      <FileBreakpoint
-         shouldBeEnabled = "No"
-         ignoreCount = "0"
-         continueAfterRunningActions = "No"
-         filePath = "VectorBoolean/FBBezierContour.m"
-         timestampString = "365637548.148902"
-         startingColumnNumber = "9223372036854775807"
-         endingColumnNumber = "9223372036854775807"
-         startingLineNumber = "36"
-         endingLineNumber = "36"
-         landmarkName = "-addCurve:"
-         landmarkType = "5">
-      </FileBreakpoint>
-   </FileBreakpoints>
-</Bucket>

VectorBoolean/CGPath_Utilities.h

     CGPathRef path
 );
 
+NSString * CGPath_FBLog (
+    CGPathRef path
+);
+
 
 #endif

VectorBoolean/CGPath_Utilities.m

 
 void CGPath_FBElementAtIndex_ApplierFunction ( void *info, const CGPathElement *element );
 void CGPath_FBElementCount_ApplierFunction ( void *info, const CGPathElement *element );
+void CGPath_FBLog_ApplierFunction ( void *info, const CGPathElement *element );
 
 
 CGPoint CGPath_FBPointAtIndex ( CGPathRef path, NSUInteger index )
     FBBezierElement element = {};
     
     // Use CGPathApply in lieu of -[NSBezierPath elementAtIndex:associatedPoints:].
-    NSMutableDictionary *dictionary = [@{ @"targetIndex" : @( index ) } mutableCopy];
+    NSMutableDictionary *dictionary = [@{ @"currentIndex" : @( 0 ), @"targetIndex" : @( index ) } mutableCopy];
     CGPathApply(path, (__bridge void *)(dictionary), CGPath_FBElementAtIndex_ApplierFunction);
     
     NSNumber *typeNumber = dictionary[@"type"];
 void CGPath_FBElementAtIndex_ApplierFunction ( void *info, const CGPathElement *element )
 {
     NSMutableDictionary *dictionary = (__bridge NSMutableDictionary *)info;
+    NSUInteger currentIndex = [dictionary[@"currentIndex"] unsignedIntegerValue];
     NSUInteger targetIndex = [dictionary[@"targetIndex"] unsignedIntegerValue];
-    NSUInteger currentIndex = [dictionary[@"currentIndex"] unsignedIntegerValue] + 1;
-    dictionary[@"currentIndex"] = @( currentIndex );
 
     if (targetIndex != currentIndex)
     {
+        dictionary[@"currentIndex"] = @( currentIndex + 1 );
         return;
     }
     
             break;
             
         case kCGPathElementCloseSubpath:
-            pointCount = 0;
+            pointCount = 1; // This must be one (as opposed to when logging)!
             break;
             
         default:
     // Package type and points.
     dictionary[@"type"]   = @( type );
     dictionary[@"points"] = pointsData;
+
+    dictionary[@"currentIndex"] = @( currentIndex + 1 );
 }
 
 
     NSUInteger *count = (NSUInteger *)info;
     (*count)++;
 }
+
+
+NSString * CGPath_FBLog ( CGPathRef path )
+{
+    NSMutableString *string = [NSMutableString stringWithFormat:@"CGPath <%#lx>", (NSUInteger)path];
+    
+    CGRect bounds = CGPathGetPathBoundingBox(path);
+    [string appendFormat:@"\n  Bounds: {{%f, %f}, {%f, %f}}",
+     bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height];
+    
+    CGRect controlBounds = CGPathGetBoundingBox(path);
+    [string appendFormat:@"\n  Control point bounds: {{%f, %f}, {%f, %f}}",
+     controlBounds.origin.x, controlBounds.origin.y, controlBounds.size.width, controlBounds.size.height];
+    
+    CGPathApply(path, (__bridge void *)(string), CGPath_FBLog_ApplierFunction);
+    return string;
+}
+
+
+void CGPath_FBLog_ApplierFunction ( void *info, const CGPathElement *element )
+{
+    NSMutableString *string = (__bridge NSMutableString *)info;
+    CGPathElementType type = element->type;
+    CGPoint *points = element->points;
+    
+    NSUInteger pointCount = 0;
+    NSString *command = @"";
+    switch (type)
+    {
+        case kCGPathElementMoveToPoint:
+            pointCount = 1;
+            command = @"moveto";
+            break;
+            
+        case kCGPathElementAddLineToPoint:
+            pointCount = 1;
+            command = @"lineto";
+            break;
+            
+        case kCGPathElementAddQuadCurveToPoint:
+            pointCount = 2;
+            command = @"quadcurveto";
+            break;
+            
+        case kCGPathElementAddCurveToPoint:
+            pointCount = 3;
+            command = @"curveto";
+            break;
+            
+        case kCGPathElementCloseSubpath:
+            pointCount = 0;
+            command = @"closepath";
+            break;
+            
+        default:
+            return;
+    }
+    
+    [string appendString:@"\n    "];
+    
+    for (NSUInteger pointIndex = 0; pointIndex < pointCount; pointIndex++)
+    {
+        [string appendFormat:@"%f %f ", points[pointIndex].x, points[pointIndex].y];
+    }
+    
+    [string appendString:command];
+}

VectorBoolean/FBBezierGraph.m

                     // Start a new contour
                     contour = [[FBBezierContour alloc] init];
                     [self addContour:contour];
-                    
                     lastPoint = element.point;
                     break;
                     
                         //  by the end points
                         FBBezierCurve *curve = [FBBezierCurve bezierCurveWithLineStartPoint:lastPoint endPoint:element.point];
                         [contour addCurve:curve];
-                        
                         lastPoint = element.point;
                     }
                     break;
                                                                      controlPoint2:element.controlPoints[1]
                                                                          endPoint2:element.point];
                     [contour addCurve:curve];
-                    
                     lastPoint = element.point;
                     break;
                 }
                 
                 case kCGPathElementAddQuadCurveToPoint:
                 default:
+                    NSLog(@"%s  Encountered unhandled element type (quad curve)", __PRETTY_FUNCTION__);
                     break;
             }
         }

VectorBoolean/FBContourEdge.m

     self = [super init];
     
     if ( self != nil ) {
+        _curve = curve;
         _crossings = [[NSMutableArray alloc] initWithCapacity:4];
         _contour = contour; // no cyclical references
     }

VectorBoolean/MyDocument.m

     [self onReset:sender];
     
     CGPathRef result = CGPath_FBCreateUnion([_view.canvas pathAtIndex:0], [_view.canvas pathAtIndex:1]);
-
-    NSUInteger elementCount = CGPath_FBElementCount(result);
-    NSLog(@"%s  elementCount: %lx", __PRETTY_FUNCTION__, elementCount);
-
     [_view.canvas clear];
     [_view.canvas addPath:result withColor:_blueColor];
     CGPathRelease(result);