views:

56

answers:

1

I've drawn two circles that overlap. I want to be able to fill and stroke them as a merged new shape.

At the moment, I create the path sequence once, stroke it, then create a copy of it, fill it and add the two identical paths on top of each other, so they appear as a single shape. Is there a better approach or is this ok?

Update: Here is a sample code:

CGMutablePathRef path = CGPathCreateMutable();

CGContextSetStrokeColorWithColor(theContext, strokeColor.CGColor);
CGContextSetLineWidth(theContext, 2);
CGContextSetFillColorWithColor(theContext, fillColor.CGColor);

CGRect rect1 = CGRectMake(0,0, mySize*0.6, mySize*0.6);
CGRect rect2 = CGRectMake(mySize*0.4,0, mySize*0.6, mySize*0.6);

CGPathAddEllipseInRect(path, NULL, rect1);
CGPathAddEllipseInRect(path, NULL, rect2);

CGContextAddPath(theContext, path);
CGContextDrawPath(theContext, kCGPathFillStroke);

CGPathRef pathFill = CGPathCreateCopy ( path );
CGContextAddPath(theContext, pathFill);
CGContextDrawPath(theContext, kCGPathFill);

CGPathRelease(path);
CGPathRelease(pathFill);

As you can see, I create a copy of the original path and draw it on top without the stroke, so in the end it looks like one united shape. Is there a way to avoid creating the duplicate?

A: 

Is there a way to avoid creating the duplicate?

Yes: Just don't create it.

Path objects in Core Graphics are paths and nothing else. They have no colors, no patterns, no fill or stroke properties, nothing—just subpaths consisting of moveto, lineto, curveto, and closepath segments.

The fill color, stroke color, line width, etc. are all properties of the graphics state in the context. The current path is also a property of the context (but not of the gstate).

When you add a path to the context, that's all you're doing: Adding the subpaths from the path object into the current path in the context. The original path object remains unchanged; it has no graphics state, and even if it did, the “add subpaths from path to context” operation changes the context, not the path object.

Similarly, filling or stroking the current path of a context only resets the current path of the context; it makes no changes to any path objects you might have used to build up that path. If it did, copying the path when you do would be too late, as the original would have already been changed—but it doesn't, so copying the path is unnecessary.

So, just add the same path object to the current path both times.

Peter Hosey
Great explanation. I definitely wasn't thinking in those terms. Thanks!
Anna