CPBezierPath controlPointBounds and CGPathGetBoundingBox.

This commit is contained in:
Alexander Ljungberg
2012-10-15 11:10:23 +01:00
parent 8819fd5fd7
commit eba3e95b81
2 changed files with 115 additions and 0 deletions
+13
View File
@@ -165,6 +165,19 @@ var DefaultLineWidth = 1.0;
CGPathAddCurveToPoint(_path, nil, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, endPoint.x, endPoint.y);
}
- (CGRect)bounds
{
// TODO: this should return this. The controlPointBounds is not a tight fit.
// return CGPathGetPathBoundingBox(_path);
return [self controlPointBounds];
}
- (CGRect)controlPointBounds
{
return CGPathGetBoundingBox(_path);
}
/*!
Create a line segment between the first and last points in the subpath, closing it.
*/
+102
View File
@@ -406,6 +406,108 @@ function CGPathIsEmpty(aPath)
return !aPath || aPath.count == 0;
}
/*!
Calculate the smallest rectangle to contain both the path of the receiver and all control points.
*/
function CGPathGetBoundingBox(aPath)
{
if (!aPath || !aPath.count)
return _CGRectMakeZero();
var ox = 0,
oy = 0,
rx = 0,
ry = 0,
movePoint = nil;
function addPoint(x, y)
{
ox = MIN(ox, x);
oy = MIN(oy, y);
rx = MAX(rx, x);
ry = MAX(ry, y);
}
for (var i = 0, count = aPath.count; i < count; ++i)
{
var element = aPath.elements[i];
// Just enclose all the control points. The curves must be inside of the control points.
// This won't work for CGPathGetPathBoundingBox.
switch (element.type)
{
case kCGPathElementAddLineToPoint:
if (movePoint)
{
addPoint(movePoint.x, movePoint.y);
movePoint = nil;
}
addPoint(element.x, element.y);
break;
case kCGPathElementAddCurveToPoint:
if (movePoint)
{
addPoint(movePoint.x, movePoint.y);
movePoint = nil;
}
addPoint(element.cp1x, element.cp1y);
addPoint(element.cp2x, element.cp2y);
addPoint(element.x, element.y);
break;
case kCGPathElementAddArc:
if (movePoint)
{
addPoint(movePoint.x, movePoint.y);
movePoint = nil;
}
addPoint(element.x, element.y);
break;
case kCGPathElementAddArcToPoint:
if (movePoint)
{
addPoint(movePoint.x, movePoint.y);
movePoint = nil;
}
addPoint(element.p1x, element.p1y);
addPoint(element.p2x, element.p2y);
break;
case kCGPathElementAddQuadCurveToPoint:
if (movePoint)
{
addPoint(movePoint.x, movePoint.y);
movePoint = nil;
}
addPoint(element.cpx, element.cpy);
addPoint(element.x, element.y);
break;
case kCGPathElementMoveToPoint:
movePoint = _CGPointMake(element.x, element.y);
break;
case kCGPathElementCloseSubpath:
if (movePoint)
{
addPoint(movePoint.x, movePoint.y);
movePoint = nil;
}
break;
}
}
return _CGRectMake(ox, oy, rx - ox, ry - oy);
}
/*!
@}
*/