mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-25 04:57:03 +00:00
Merge remote-tracking branch 'upstream/master' into CPTableViewLion
Conflicts: Tests/Manual/CPOutlineViewCibTest/Resources/MainMenu.cib
This commit is contained in:
@@ -177,7 +177,7 @@ var DefaultLineWidth = 1.0;
|
||||
- (CGRect)bounds
|
||||
{
|
||||
// TODO: this should return this. The controlPointBounds is not a tight fit.
|
||||
// return CGPathGetPathBoundingBox(_path);
|
||||
// return CGPathGetBoundingBox(_path);
|
||||
|
||||
return [self controlPointBounds];
|
||||
}
|
||||
|
||||
@@ -1197,13 +1197,14 @@ Not supported. Use -collectionView:dataForItemsAtIndexes:fortype:
|
||||
|
||||
//draw white under the circle thing
|
||||
CGContextFillRect(context, circleRect);
|
||||
|
||||
//draw the circle thing
|
||||
CGContextStrokeEllipseInRect(context, circleRect);
|
||||
|
||||
//then draw the line
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, FLOOR(width / 2), _CGRectGetMinY(aRect) + width);
|
||||
CGContextAddLineToPoint(context, FLOOR(width / 2), _CGRectGetHeight(aRect));
|
||||
CGContextClosePath(context);
|
||||
CGContextStrokePath(context);
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ var CPGraphicsContextCurrent = nil,
|
||||
+ (void)restoreGraphicsState
|
||||
{
|
||||
var lastContext = [CPGraphicsContextThreadStack lastObject];
|
||||
|
||||
if (lastContext)
|
||||
{
|
||||
[lastContext restoreGraphicsState];
|
||||
|
||||
@@ -302,6 +302,14 @@ function CPAppKitImage(aFilename, aSize)
|
||||
return _name;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the underlying Image element for a single image.
|
||||
*/
|
||||
- (Image)image
|
||||
{
|
||||
return _image;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the receiver's delegate.
|
||||
@param the delegate
|
||||
@@ -390,6 +398,11 @@ function CPAppKitImage(aFilename, aSize)
|
||||
#endif
|
||||
}
|
||||
|
||||
- (BOOL)isSingleImage
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)isThreePartImage
|
||||
{
|
||||
return NO;
|
||||
@@ -521,6 +534,11 @@ function CPAppKitImage(aFilename, aSize)
|
||||
return _isVertical;
|
||||
}
|
||||
|
||||
- (BOOL)isSingleImage
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)isThreePartImage
|
||||
{
|
||||
return YES;
|
||||
@@ -585,6 +603,11 @@ var CPThreePartImageImageSlicesKey = @"CPThreePartImageImageSlicesKey",
|
||||
return _imageSlices;
|
||||
}
|
||||
|
||||
- (BOOL)isSingleImage
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)isThreePartImage
|
||||
{
|
||||
return NO;
|
||||
|
||||
@@ -247,8 +247,6 @@
|
||||
CGContextMoveToPoint(context, 1.0, 4.0);
|
||||
CGContextAddLineToPoint(context, 9.0, 4.0);
|
||||
CGContextAddLineToPoint(context, 5.0, 8.0);
|
||||
CGContextAddLineToPoint(context, 1.0, 4.0);
|
||||
|
||||
CGContextClosePath(context);
|
||||
|
||||
CGContextSetFillColor(context, _color);
|
||||
|
||||
@@ -1955,9 +1955,8 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
|
||||
CGContextMoveToPoint(context, 0.0, 0.0);
|
||||
CGContextAddLineToPoint(context, 9.0, 0.0);
|
||||
CGContextAddLineToPoint(context, 4.5, 8.0);
|
||||
CGContextAddLineToPoint(context, 0.0, 0.0);
|
||||
|
||||
CGContextClosePath(context);
|
||||
|
||||
CGContextSetFillColor(context,
|
||||
colorForDisclosureTriangle([self hasThemeState:CPThemeStateSelected],
|
||||
[self hasThemeState:CPThemeStateHighlighted]));
|
||||
@@ -1965,8 +1964,8 @@ var _loadItemInfoForItem = function(/*CPOutlineView*/ anOutlineView, /*id*/ anIt
|
||||
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, 0.0, 0.0);
|
||||
|
||||
CGContextAddLineToPoint(context, 4.5, 8.0);
|
||||
|
||||
if (_angle === 0.0)
|
||||
CGContextAddLineToPoint(context, 9.0, 0.0);
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
maxX = CGRectGetWidth(bounds),
|
||||
maxY = CGRectGetHeight(bounds);
|
||||
|
||||
// Draw background
|
||||
// Draw background
|
||||
if ([self _isSelected])
|
||||
_backgroundColor = [_ruleEditor _selectedRowColor];
|
||||
else
|
||||
@@ -78,20 +78,20 @@
|
||||
CGContextSetFillColor(context, _backgroundColor);
|
||||
CGContextFillRect(context, rect);
|
||||
|
||||
// Draw Top Border
|
||||
// Draw Top Border
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, 0, 0);
|
||||
CGContextAddLineToPoint(context, maxX, 0);
|
||||
CGContextClosePath(context);
|
||||
CGContextSetStrokeColor(context, [_ruleEditor _sliceTopBorderColor]);
|
||||
CGContextStrokePath(context);
|
||||
|
||||
// Draw Bottom Border
|
||||
// Draw Bottom Border
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, 0, maxY);
|
||||
CGContextAddLineToPoint(context, maxX, maxY);
|
||||
CGContextClosePath(context);
|
||||
|
||||
var bottomColor = (_rowIndex == [_ruleEditor _lastRow]) ? [_ruleEditor _sliceLastBottomBorderColor] : [_ruleEditor _sliceBottomBorderColor];
|
||||
|
||||
CGContextSetStrokeColor(context, bottomColor);
|
||||
CGContextStrokePath(context);
|
||||
}
|
||||
|
||||
@@ -554,7 +554,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
||||
[self stopTrackingTableColumn:_activeColumn at:aLocation];
|
||||
|
||||
[self setNeedsDisplay:YES];
|
||||
|
||||
|
||||
[_tableView _enqueueDraggingViews];
|
||||
}
|
||||
|
||||
@@ -704,6 +704,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
||||
columnMaxX;
|
||||
|
||||
CGContextBeginPath(context);
|
||||
|
||||
for (; columnArrayIndex < columnArrayCount; columnArrayIndex++)
|
||||
{
|
||||
// grab each column rect and add vertical lines
|
||||
@@ -715,6 +716,7 @@ var _CPTableColumnHeaderViewStringValueKey = @"_CPTableColumnHeaderViewStringVal
|
||||
CGContextMoveToPoint(context, FLOOR(columnMaxX) - 0.5, ROUND(_CGRectGetMinY(columnToStroke)));
|
||||
CGContextAddLineToPoint(context, FLOOR(columnMaxX) - 0.5, ROUND(_CGRectGetMaxY(columnToStroke)) - 1.0);
|
||||
}
|
||||
|
||||
CGContextClosePath(context);
|
||||
CGContextStrokePath(context);
|
||||
|
||||
|
||||
+8
-10
@@ -3908,6 +3908,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
while (colorIndex < colorCount)
|
||||
{
|
||||
CGContextBeginPath(context);
|
||||
|
||||
for (var row = firstRow + colorIndex; row <= lastRow; row += colorCount)
|
||||
{
|
||||
// if it's not a group row draw it otherwise we draw it later
|
||||
@@ -3916,6 +3917,7 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
else
|
||||
groupRowRects.push(CGRectIntersection(aRect, [self _rectOfRow:row checkRange:NO]));
|
||||
}
|
||||
|
||||
CGContextClosePath(context);
|
||||
|
||||
CGContextSetFillColor(context, rowColors[colorIndex]);
|
||||
@@ -4088,22 +4090,20 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
CGContextFillPath(context);
|
||||
CGContextBeginPath(context);
|
||||
}
|
||||
|
||||
CGContextAddRect(context, rowRect);
|
||||
|
||||
CGContextDrawLinearGradient(context, (shouldUseGroupGradient) ? gradientGroupColor : gradientColor, rowRect.origin, _CGPointMake(minX, maxY), 0);
|
||||
CGContextClosePath(context);
|
||||
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, minX, minY + .5);
|
||||
CGContextAddLineToPoint(context, maxX, minY + .5);
|
||||
CGContextClosePath(context);
|
||||
CGContextSetStrokeColor(context, (shouldUseGroupGradient) ? topGroupLineColor : topLineColor);
|
||||
CGContextStrokePath(context);
|
||||
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, minX, maxY - .5);
|
||||
CGContextAddLineToPoint(context, maxX, maxY - .5);
|
||||
CGContextClosePath(context);
|
||||
CGContextSetStrokeColor(context, (shouldUseGroupGradient) ? bottomGroupLineColor : bottomLineColor);
|
||||
CGContextStrokePath(context);
|
||||
}
|
||||
@@ -4138,7 +4138,9 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
}
|
||||
|
||||
CGContextBeginPath(context);
|
||||
|
||||
var gridStyleMask = [self gridStyleMask];
|
||||
|
||||
for (var i = 0; i < count2; i++)
|
||||
{
|
||||
var rect = objj_msgSend(self, rectSelector, indexes[i]),
|
||||
@@ -4153,7 +4155,9 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
exposedColumnIndexes = [],
|
||||
firstExposedColumn = [exposedColumns firstIndex],
|
||||
exposedRange = CPMakeRange(firstExposedColumn, [exposedColumns lastIndex] - firstExposedColumn + 1);
|
||||
|
||||
[exposedColumns getIndexes:exposedColumnIndexes maxCount:-1 inIndexRange:exposedRange];
|
||||
|
||||
var exposedColumnCount = [exposedColumnIndexes count];
|
||||
|
||||
for (var c = firstExposedColumn; c < exposedColumnCount; c++)
|
||||
@@ -4215,25 +4219,20 @@ Your delegate can implement this method to avoid subclassing the tableview to ad
|
||||
maxY = CGRectGetMaxY(rowRect);
|
||||
|
||||
CGContextDrawLinearGradient(context, gradientColor, rowRect.origin, CGPointMake(minX, maxY), 0);
|
||||
CGContextClosePath(context);
|
||||
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, minX, minY);
|
||||
CGContextAddLineToPoint(context, maxX, minY);
|
||||
CGContextClosePath(context);
|
||||
CGContextSetStrokeColor(context, topLineColor);
|
||||
CGContextStrokePath(context);
|
||||
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, minX, maxY);
|
||||
CGContextAddLineToPoint(context, maxX, maxY - 1);
|
||||
CGContextClosePath(context);
|
||||
CGContextSetStrokeColor(context, bottomLineColor);
|
||||
CGContextStrokePath(context);
|
||||
}
|
||||
}
|
||||
|
||||
CGContextClosePath(context);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -5403,6 +5402,7 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
|
||||
CGContextSetFillColor(context, [CPColor colorWithRed:72 / 255 green:134 / 255 blue:202 / 255 alpha:0.25]);
|
||||
CGContextFillRoundedRectangleInRect(context, newRect, 8, YES, YES, YES, YES);
|
||||
}
|
||||
|
||||
CGContextStrokeRoundedRectangleInRect(context, newRect, 8, YES, YES, YES, YES);
|
||||
|
||||
}
|
||||
@@ -5423,7 +5423,6 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, 10, aRect.origin.y + 8);
|
||||
CGContextAddLineToPoint(context, aRect.size.width - aRect.origin.y - 8, aRect.origin.y + 8);
|
||||
CGContextClosePath(context);
|
||||
CGContextStrokePath(context);
|
||||
|
||||
CGContextSetStrokeColor(context, [CPColor colorWithHexString:@"4886ca"]);
|
||||
@@ -5436,7 +5435,6 @@ var CPTableViewDataSourceKey = @"CPTableViewDataSourceKey",
|
||||
CGContextBeginPath(context);
|
||||
CGContextMoveToPoint(context, 10, aRect.origin.y + 8);
|
||||
CGContextAddLineToPoint(context, aRect.size.width - aRect.origin.y - 8, aRect.origin.y + 8);
|
||||
CGContextClosePath(context);
|
||||
CGContextStrokePath(context);
|
||||
//CGContextStrokeLineSegments(context, [aRect.origin.x + 8, aRect.origin.y + 8, 300 , aRect.origin.y + 8]);
|
||||
}
|
||||
|
||||
@@ -189,6 +189,7 @@ var _CPPopoverWindowViewDefaultCursorSize = _CGSizeMake(16, 10),
|
||||
|
||||
CGContextSetStrokeColor(context, strokeColor);
|
||||
CGContextSetLineWidth(context, strokeWidth);
|
||||
|
||||
CGContextBeginPath(context);
|
||||
CGContextSetShadowWithColor(context, shadowSize, shadowBlur, shadowColor);
|
||||
CGContextDrawLinearGradient(context, gradient, _CGPointMake(_CGRectGetMidX(frame), 0.0), _CGPointMake(_CGRectGetMidX(frame), frame.size.height), 0);
|
||||
@@ -206,6 +207,8 @@ var _CPPopoverWindowViewDefaultCursorSize = _CGSizeMake(16, 10),
|
||||
pt = _CGPointMakeZero();
|
||||
|
||||
// draw!
|
||||
var path = CGPathCreateMutable();
|
||||
|
||||
switch (_preferredEdge)
|
||||
{
|
||||
case CPMinXEdge:
|
||||
@@ -213,12 +216,12 @@ var _CPPopoverWindowViewDefaultCursorSize = _CGSizeMake(16, 10),
|
||||
// origin nw
|
||||
pt.x = CGAlignCoordinate(xMin + radius);
|
||||
pt.y = yMin;
|
||||
CGContextMoveToPoint(context, pt.x, pt.y);
|
||||
CGPathMoveToPoint(path, NULL, pt.x, pt.y);
|
||||
|
||||
// ne
|
||||
pt.x = CGAlignCoordinate(xMax - radius);
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGContextAddCurveToPoint(context, pt.x, pt.y, xMax, yMin, xMax, CGAlignCoordinate(yMin + radius));
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
CGPathAddCurveToPoint(path, NULL, pt.x, pt.y, xMax, yMin, xMax, CGAlignCoordinate(yMin + radius));
|
||||
|
||||
if (_preferredEdge === CPMinXEdge)
|
||||
{
|
||||
@@ -237,30 +240,30 @@ var _CPPopoverWindowViewDefaultCursorSize = _CGSizeMake(16, 10),
|
||||
|
||||
pt.x = arrowAnchor.x;
|
||||
arrowStart = _CGPointMakeCopy(pt);
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
|
||||
// top edge -> point
|
||||
pt.x = CGAlignStroke(arrowAnchor.x + arrowHeight, strokeWidth);
|
||||
pt.y = arrowAnchor.y;
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
|
||||
// point -> bottom edge
|
||||
pt.x = arrowAnchor.x;
|
||||
pt.y = CGAlignCoordinate(arrowStart.y + arrowWidth);
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
}
|
||||
|
||||
// se
|
||||
pt.x = xMax;
|
||||
pt.y = CGAlignCoordinate(yMax - radius);
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGContextAddCurveToPoint(context, pt.x, pt.y, pt.x, yMax, CGAlignCoordinate(xMax - radius), yMax);
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
CGPathAddCurveToPoint(path, NULL, pt.x, pt.y, pt.x, yMax, CGAlignCoordinate(xMax - radius), yMax);
|
||||
|
||||
// sw
|
||||
pt.x = CGAlignCoordinate(xMin + radius);
|
||||
pt.y = yMax;
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGContextAddCurveToPoint(context, pt.x, pt.y, xMin, pt.y, xMin, CGAlignCoordinate(yMax - radius));
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
CGPathAddCurveToPoint(path, NULL, pt.x, pt.y, xMin, pt.y, xMin, CGAlignCoordinate(yMax - radius));
|
||||
|
||||
if (_preferredEdge === CPMaxXEdge)
|
||||
{
|
||||
@@ -279,24 +282,24 @@ var _CPPopoverWindowViewDefaultCursorSize = _CGSizeMake(16, 10),
|
||||
|
||||
pt.x = arrowAnchor.x;
|
||||
arrowStart = _CGPointMakeCopy(pt);
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
|
||||
// bottom edge -> point
|
||||
pt.x = CGAlignStroke(arrowAnchor.x - arrowHeight, strokeWidth);
|
||||
pt.y = arrowAnchor.y;
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
|
||||
// point -> top edge
|
||||
pt.x = arrowAnchor.x;
|
||||
pt.y = CGAlignCoordinate(arrowStart.y - arrowWidth);
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
}
|
||||
|
||||
// nw
|
||||
pt.x = xMin;
|
||||
pt.y = CGAlignCoordinate(yMin + radius);
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGContextAddCurveToPoint(context, pt.x, pt.y, pt.x, yMin, CGAlignCoordinate(xMin + radius), yMin);
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
CGPathAddCurveToPoint(path, NULL, pt.x, pt.y, pt.x, yMin, CGAlignCoordinate(xMin + radius), yMin);
|
||||
break;
|
||||
|
||||
case CPMaxYEdge:
|
||||
@@ -304,12 +307,12 @@ var _CPPopoverWindowViewDefaultCursorSize = _CGSizeMake(16, 10),
|
||||
// origin sw
|
||||
pt.x = xMin;
|
||||
pt.y = CGAlignCoordinate(yMax - radius);
|
||||
CGContextMoveToPoint(context, pt.x, pt.y);
|
||||
CGPathMoveToPoint(path, NULL, pt.x, pt.y);
|
||||
|
||||
// nw
|
||||
pt.y = CGAlignCoordinate(yMin + radius);
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGContextAddCurveToPoint(context, pt.x, pt.y, pt.x, yMin, CGAlignCoordinate(xMin + radius), yMin);
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
CGPathAddCurveToPoint(path, NULL, pt.x, pt.y, pt.x, yMin, CGAlignCoordinate(xMin + radius), yMin);
|
||||
|
||||
if (_preferredEdge === CPMaxYEdge)
|
||||
{
|
||||
@@ -328,30 +331,30 @@ var _CPPopoverWindowViewDefaultCursorSize = _CGSizeMake(16, 10),
|
||||
|
||||
pt.y = arrowAnchor.y;
|
||||
arrowStart = _CGPointMakeCopy(pt);
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
|
||||
// left edge -> point
|
||||
pt.x = arrowAnchor.x;
|
||||
pt.y = CGAlignStroke(arrowAnchor.y - arrowHeight, strokeWidth);
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
|
||||
// point -> right edge
|
||||
pt.x = CGAlignCoordinate(arrowStart.x + arrowWidth);
|
||||
pt.y = arrowAnchor.y;
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
}
|
||||
|
||||
// ne
|
||||
pt.x = CGAlignCoordinate(xMax - radius);
|
||||
pt.y = yMin;
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGContextAddCurveToPoint(context, pt.x, pt.y, xMax, pt.y, xMax, CGAlignCoordinate(yMin + radius));
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
CGPathAddCurveToPoint(path, NULL, pt.x, pt.y, xMax, pt.y, xMax, CGAlignCoordinate(yMin + radius));
|
||||
|
||||
// se
|
||||
pt.x = xMax;
|
||||
pt.y = CGAlignCoordinate(yMax - radius);
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGContextAddCurveToPoint(context, pt.x, pt.y, pt.x, yMax, CGAlignCoordinate(xMax - radius), yMax);
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
CGPathAddCurveToPoint(path, NULL, pt.x, pt.y, pt.x, yMax, CGAlignCoordinate(xMax - radius), yMax);
|
||||
|
||||
if (_preferredEdge === CPMinYEdge)
|
||||
{
|
||||
@@ -370,33 +373,35 @@ var _CPPopoverWindowViewDefaultCursorSize = _CGSizeMake(16, 10),
|
||||
|
||||
pt.y = arrowAnchor.y;
|
||||
arrowStart = _CGPointMakeCopy(pt);
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
|
||||
// right edge -> point
|
||||
pt.x = arrowAnchor.x;
|
||||
pt.y = CGAlignStroke(arrowAnchor.y + arrowHeight, strokeWidth);
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
|
||||
// point -> left edge
|
||||
pt.x = CGAlignCoordinate(arrowStart.x - arrowWidth);
|
||||
pt.y = arrowAnchor.y;
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
}
|
||||
|
||||
// sw
|
||||
pt.x = CGAlignCoordinate(xMin + radius);
|
||||
pt.y = yMax;
|
||||
CGContextAddLineToPoint(context, pt.x, pt.y);
|
||||
CGContextAddCurveToPoint(context, pt.x, pt.y, xMin, pt.y, xMin, CGAlignCoordinate(yMax - radius));
|
||||
CGPathAddLineToPoint(path, NULL, pt.x, pt.y);
|
||||
CGPathAddCurveToPoint(path, NULL, pt.x, pt.y, xMin, pt.y, xMin, CGAlignCoordinate(yMax - radius));
|
||||
break;
|
||||
|
||||
default:
|
||||
// no computed edge means standard rounded rect
|
||||
CGContextAddPath(context, CGPathWithRoundedRectangleInRect(frame, radius, radius, YES, YES, YES, YES));
|
||||
CGPathAddPath(path, NULL, CGPathWithRoundedRectangleInRect(frame, radius, radius, YES, YES, YES, YES));
|
||||
}
|
||||
|
||||
CGContextClosePath(context);
|
||||
CGContextAddPath(context, path);
|
||||
CGContextStrokePath(context);
|
||||
|
||||
CGContextAddPath(context, path);
|
||||
CGContextFillPath(context);
|
||||
}
|
||||
|
||||
|
||||
@@ -99,17 +99,17 @@
|
||||
CGContextSetStrokeColor(context, strokeColor);
|
||||
CGContextSetFillColor(context, bgColor);
|
||||
CGContextSetLineWidth(context, strokeWidth);
|
||||
CGContextBeginPath(context);
|
||||
|
||||
aRect.origin.x += strokeWidth;
|
||||
aRect.origin.y += strokeWidth;
|
||||
aRect.size.width -= strokeWidth * 2;
|
||||
aRect.size.height -= strokeWidth * 2;
|
||||
|
||||
CGContextAddPath(context, CGPathWithRoundedRectangleInRect(aRect, radius, radius, YES, YES, YES, YES));
|
||||
CGContextClosePath(context);
|
||||
|
||||
var path = CGPathWithRoundedRectangleInRect(aRect, radius, radius, YES, YES, YES, YES);
|
||||
CGContextAddPath(context, path);
|
||||
CGContextStrokePath(context);
|
||||
|
||||
CGContextAddPath(context, path);
|
||||
CGContextFillPath(context);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,16 @@ var CANVAS_LINECAP_TABLE = [ "butt", "round", "square" ],
|
||||
#define _CGContextFillRectCanvas(aContext, aRect) aContext.fillRect(_CGRectGetMinX(aRect), _CGRectGetMinY(aRect), _CGRectGetWidth(aRect), _CGRectGetHeight(aRect))
|
||||
#define _CGContextClipCanvas(aContext) aContext.clip()
|
||||
|
||||
// In Cocoa, all primitives excepts rects cannot be added to the context's path
|
||||
// until a move to point has been done, because an empty path has no current point.
|
||||
var hasPath = function(aContext, methodName)
|
||||
{
|
||||
if (!aContext.hasPath)
|
||||
CPLog.error(methodName + ": no current point");
|
||||
|
||||
return aContext.hasPath;
|
||||
}
|
||||
|
||||
function CGContextSaveGState(aContext)
|
||||
{
|
||||
aContext.save();
|
||||
@@ -80,6 +90,9 @@ function CGContextSetBlendMode(aContext, aBlendMode)
|
||||
|
||||
function CGContextAddArc(aContext, x, y, radius, startAngle, endAngle, clockwise)
|
||||
{
|
||||
if (!hasPath(aContext, "CGContextAddArc"))
|
||||
return;
|
||||
|
||||
// Despite the documentation saying otherwise, the last parameter is anti-clockwise not clockwise.
|
||||
// http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes#Arcs
|
||||
_CGContextAddArcCanvas(aContext, x, y, radius, startAngle, endAngle, !clockwise);
|
||||
@@ -87,11 +100,17 @@ function CGContextAddArc(aContext, x, y, radius, startAngle, endAngle, clockwise
|
||||
|
||||
function CGContextAddArcToPoint(aContext, x1, y1, x2, y2, radius)
|
||||
{
|
||||
if (!hasPath(aContext, "CGContextAddArcToPoint"))
|
||||
return;
|
||||
|
||||
_CGContextAddArcToPointCanvas(aContext, x1, y1, x2, y2, radius);
|
||||
}
|
||||
|
||||
function CGContextAddCurveToPoint(aContext, cp1x, cp1y, cp2x, cp2y, x, y)
|
||||
{
|
||||
if (!hasPath(aContext, "CGContextAddCurveToPoint"))
|
||||
return;
|
||||
|
||||
_CGContextAddCurveToPointCanvas(aContext, cp1x, cp1y, cp2x, cp2y, x, y);
|
||||
}
|
||||
|
||||
@@ -108,10 +127,15 @@ function CGContextAddLines(aContext, points, count)
|
||||
|
||||
for (var i = 1; i < count; ++i)
|
||||
_CGContextAddLineToPointCanvas(aContext, points[i].x, points[i].y);
|
||||
|
||||
aContext.hasPath = YES;
|
||||
}
|
||||
|
||||
function CGContextAddLineToPoint(aContext, x, y)
|
||||
{
|
||||
if (!hasPath(aContext, "CGContextAddLineToPoint"))
|
||||
return;
|
||||
|
||||
_CGContextAddLineToPointCanvas(aContext, x, y);
|
||||
}
|
||||
|
||||
@@ -120,6 +144,13 @@ function CGContextAddPath(aContext, aPath)
|
||||
if (!aContext || CGPathIsEmpty(aPath))
|
||||
return;
|
||||
|
||||
// If the context does not have a path, explicitly begin one
|
||||
if (!aContext.hasPath)
|
||||
_CGContextBeginPathCanvas(aContext);
|
||||
|
||||
// We must implicitly move to the start of the path
|
||||
_CGContextMoveToPointCanvas(aContext, aPath.start.x, aPath.start.y);
|
||||
|
||||
var elements = aPath.elements,
|
||||
i = 0,
|
||||
count = aPath.count;
|
||||
@@ -131,31 +162,50 @@ function CGContextAddPath(aContext, aPath)
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case kCGPathElementMoveToPoint: _CGContextMoveToPointCanvas(aContext, element.x, element.y);
|
||||
break;
|
||||
case kCGPathElementAddLineToPoint: _CGContextAddLineToPointCanvas(aContext, element.x, element.y);
|
||||
break;
|
||||
case kCGPathElementAddQuadCurveToPoint: _CGContextAddQuadCurveToPointCanvas(aContext, element.cpx, element.cpy, element.x, element.y);
|
||||
break;
|
||||
case kCGPathElementAddCurveToPoint: _CGContextAddCurveToPointCanvas(aContext, element.cp1x, element.cp1y, element.cp2x, element.cp2y, element.x, element.y);
|
||||
break;
|
||||
case kCGPathElementCloseSubpath: _CGContextClosePathCanvas(aContext);
|
||||
break;
|
||||
case kCGPathElementAddArc: _CGContextAddArcCanvas(aContext, element.x, element.y, element.radius, element.startAngle, element.endAngle, element.clockwise);
|
||||
break;
|
||||
case kCGPathElementAddArcToPoint: _CGContextAddArcToPointCanvas(aContext, element.p1x, element.p1y, element.p2x, element.p2y, element.radius);
|
||||
break;
|
||||
case kCGPathElementMoveToPoint:
|
||||
_CGContextMoveToPointCanvas(aContext, element.x, element.y);
|
||||
break;
|
||||
|
||||
case kCGPathElementAddLineToPoint:
|
||||
_CGContextAddLineToPointCanvas(aContext, element.x, element.y);
|
||||
break;
|
||||
|
||||
case kCGPathElementAddQuadCurveToPoint:
|
||||
_CGContextAddQuadCurveToPointCanvas(aContext, element.cpx, element.cpy, element.x, element.y);
|
||||
break;
|
||||
|
||||
case kCGPathElementAddCurveToPoint:
|
||||
_CGContextAddCurveToPointCanvas(aContext, element.cp1x, element.cp1y, element.cp2x, element.cp2y, element.x, element.y);
|
||||
break;
|
||||
|
||||
case kCGPathElementCloseSubpath:
|
||||
_CGContextClosePathCanvas(aContext);
|
||||
break;
|
||||
|
||||
case kCGPathElementAddArc:
|
||||
_CGContextAddArcCanvas(aContext, element.x, element.y, element.radius, element.startAngle, element.endAngle, element.clockwise);
|
||||
break;
|
||||
|
||||
case kCGPathElementAddArcToPoint:
|
||||
_CGContextAddArcToPointCanvas(aContext, element.p1x, element.p1y, element.p2x, element.p2y, element.radius);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
aContext.hasPath = YES;
|
||||
}
|
||||
|
||||
function CGContextAddRect(aContext, aRect)
|
||||
{
|
||||
_CGContextAddRectCanvas(aContext, aRect);
|
||||
aContext.hasPath = YES;
|
||||
}
|
||||
|
||||
function CGContextAddQuadCurveToPoint(aContext, cpx, cpy, x, y)
|
||||
{
|
||||
if (!hasPath(aContext, "CGContextAddQuadCurveToPoint"))
|
||||
return;
|
||||
|
||||
_CGContextAddQuadCurveToPointCanvas(aContext, cpx, cpy, x, y);
|
||||
}
|
||||
|
||||
@@ -169,11 +219,14 @@ function CGContextAddRects(aContext, rects, count)
|
||||
var rect = rects[i];
|
||||
_CGContextAddRectCanvas(aContext, rect);
|
||||
}
|
||||
|
||||
aContext.hasPath = YES;
|
||||
}
|
||||
|
||||
function CGContextBeginPath(aContext)
|
||||
{
|
||||
_CGContextBeginPathCanvas(aContext);
|
||||
aContext.hasPath = NO;
|
||||
}
|
||||
|
||||
function CGContextClosePath(aContext)
|
||||
@@ -181,30 +234,42 @@ function CGContextClosePath(aContext)
|
||||
_CGContextClosePathCanvas(aContext);
|
||||
}
|
||||
|
||||
function CGContextIsPathEmpty(aContext)
|
||||
{
|
||||
return !aContext.hasPath;
|
||||
}
|
||||
|
||||
function CGContextMoveToPoint(aContext, x, y)
|
||||
{
|
||||
_CGContextMoveToPointCanvas(aContext, x, y);
|
||||
aContext.hasPath = YES;
|
||||
}
|
||||
|
||||
function CGContextClearRect(aContext, aRect)
|
||||
{
|
||||
aContext.clearRect(_CGRectGetMinX(aRect), _CGRectGetMinY(aRect), _CGRectGetWidth(aRect), _CGRectGetHeight(aRect));
|
||||
aContext.hasPath = NO;
|
||||
}
|
||||
|
||||
function CGContextDrawPath(aContext, aMode)
|
||||
{
|
||||
if (aMode == kCGPathFill || aMode == kCGPathFillStroke)
|
||||
aContext.fill();
|
||||
else if (aMode == kCGPathEOFill || aMode == kCGPathEOFillStroke)
|
||||
alert("not implemented!!!");
|
||||
if (!aContext.hasPath)
|
||||
return;
|
||||
|
||||
if (aMode == kCGPathStroke || aMode == kCGPathFillStroke || aMode == kCGPathEOFillStroke)
|
||||
if (aMode === kCGPathFill || aMode === kCGPathFillStroke)
|
||||
aContext.fill();
|
||||
else if (aMode === kCGPathStroke || aMode === kCGPathFillStroke || aMode === kCGPathEOFillStroke)
|
||||
aContext.stroke();
|
||||
else if (aMode === kCGPathEOFill || aMode === kCGPathEOFillStroke)
|
||||
CPLog.warn("Unimplemented fill mode in CGContextDrawPath: %d", aMode);
|
||||
|
||||
aContext.hasPath = NO;
|
||||
}
|
||||
|
||||
function CGContextFillRect(aContext, aRect)
|
||||
{
|
||||
_CGContextFillRectCanvas(aContext, aRect);
|
||||
aContext.hasPath = NO;
|
||||
}
|
||||
|
||||
function CGContextFillRects(aContext, rects, count)
|
||||
@@ -217,16 +282,20 @@ function CGContextFillRects(aContext, rects, count)
|
||||
var rect = rects[i];
|
||||
_CGContextFillRectCanvas(aContext, rect);
|
||||
}
|
||||
|
||||
aContext.hasPath = NO;
|
||||
}
|
||||
|
||||
function CGContextStrokeRect(aContext, aRect)
|
||||
{
|
||||
aContext.strokeRect(_CGRectGetMinX(aRect), _CGRectGetMinY(aRect), _CGRectGetWidth(aRect), _CGRectGetHeight(aRect));
|
||||
aContext.hasPath = NO;
|
||||
}
|
||||
|
||||
function CGContextClip(aContext)
|
||||
{
|
||||
_CGContextClipCanvas(aContext);
|
||||
aContext.hasPath = NO;
|
||||
}
|
||||
|
||||
function CGContextClipToRect(aContext, aRect)
|
||||
@@ -236,6 +305,7 @@ function CGContextClipToRect(aContext, aRect)
|
||||
_CGContextClosePathCanvas(aContext);
|
||||
|
||||
_CGContextClipCanvas(aContext);
|
||||
aContext.hasPath = NO;
|
||||
}
|
||||
|
||||
function CGContextClipToRects(aContext, rects, count)
|
||||
@@ -246,6 +316,7 @@ function CGContextClipToRects(aContext, rects, count)
|
||||
_CGContextBeginPathCanvas(aContext);
|
||||
CGContextAddRects(aContext, rects, count);
|
||||
_CGContextClipCanvas(aContext);
|
||||
aContext.hasPath = NO;
|
||||
}
|
||||
|
||||
function CGContextSetAlpha(aContext, anAlpha)
|
||||
@@ -255,20 +326,11 @@ function CGContextSetAlpha(aContext, anAlpha)
|
||||
|
||||
function CGContextSetFillColor(aContext, aColor)
|
||||
{
|
||||
if ([aColor patternImage])
|
||||
var patternImage = [aColor patternImage];
|
||||
|
||||
if ([patternImage isSingleImage])
|
||||
{
|
||||
var patternImg = [aColor patternImage],
|
||||
size = [patternImg size],
|
||||
img;
|
||||
|
||||
if (size)
|
||||
img = new Image(size.width, size.height);
|
||||
else
|
||||
img = new Image();
|
||||
|
||||
img.src = [patternImg filename];
|
||||
|
||||
var pattern = aContext.createPattern(img, "repeat");
|
||||
var pattern = aContext.createPattern([patternImage image], "repeat");
|
||||
|
||||
aContext.fillStyle = pattern;
|
||||
}
|
||||
@@ -276,9 +338,54 @@ function CGContextSetFillColor(aContext, aColor)
|
||||
aContext.fillStyle = [aColor cssString];
|
||||
}
|
||||
|
||||
/*!
|
||||
Creates a context into which you can render a fill pattern
|
||||
of the given size. Once the pattern is rendered, you can
|
||||
set the fill or stroke pattern to the rendered pattern
|
||||
with CGContextSetFillPattern or CGContextSetStrokePattern.
|
||||
*/
|
||||
function CGContextCreatePatternContext(aContext, aSize)
|
||||
{
|
||||
var pattern = document.createElement("canvas");
|
||||
|
||||
pattern.width = aSize.width;
|
||||
pattern.height = aSize.height;
|
||||
|
||||
return pattern.getContext("2d");
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the fill pattern for aContext to the rendered pattern context
|
||||
returned by CGContextCreatePatternContext.
|
||||
*/
|
||||
function CGContextSetFillPattern(aContext, aPatternContext)
|
||||
{
|
||||
var pattern = aContext.createPattern(aPatternContext.canvas, "repeat");
|
||||
aContext.fillStyle = pattern;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the stroke pattern for aContext to the rendered pattern context
|
||||
returned by CGContextCreatePatternContext.
|
||||
*/
|
||||
function CGContextSetStrokePattern(aContext, aPatternContext)
|
||||
{
|
||||
var pattern = aContext.createPattern(aPatternContext.canvas, "repeat");
|
||||
aContext.strokeStyle = pattern;
|
||||
}
|
||||
|
||||
function CGContextSetStrokeColor(aContext, aColor)
|
||||
{
|
||||
aContext.strokeStyle = [aColor cssString];
|
||||
var patternImage = [aColor patternImage];
|
||||
|
||||
if ([patternImage isSingleImage])
|
||||
{
|
||||
var pattern = aContext.createPattern([patternImage image], "repeat");
|
||||
|
||||
aContext.strokeStyle = pattern;
|
||||
}
|
||||
else
|
||||
aContext.strokeStyle = [aColor cssString];
|
||||
}
|
||||
|
||||
function CGContextSetShadow(aContext, aSize, aBlur)
|
||||
@@ -311,59 +418,63 @@ function CGContextTranslateCTM(aContext, tx, ty)
|
||||
aContext.translate(tx, ty);
|
||||
}
|
||||
|
||||
#define scale_rotate(a, b, c, d) \
|
||||
var sign = (a * d < 0.0 || b * c > 0.0) ? -1.0 : 1.0, \
|
||||
a2 = (ATAN2(b, d) + ATAN2(-sign * c, sign * a)) / 2.0, \
|
||||
cos = COS(a2),\
|
||||
sin = SIN(a2);\
|
||||
\
|
||||
if (cos == 0)\
|
||||
{\
|
||||
sx = -c / sin;\
|
||||
sy = b / sin;\
|
||||
}\
|
||||
else if (sin == 0)\
|
||||
{\
|
||||
sx = a / cos;\
|
||||
sy = d / cos;\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
abs_cos = ABS(cos);\
|
||||
abs_sin = ABS(sin);\
|
||||
\
|
||||
sx = (abs_cos * a / cos + abs_sin * -c / sin) / (abs_cos + abs_sin);\
|
||||
sy = (abs_cos * d / cos + abs_sin * b / sin) / (abs_cos + abs_sin);\
|
||||
}\
|
||||
var scale_rotate = function(a, b, c, d)
|
||||
{
|
||||
var sign = (a * d < 0.0 || b * c > 0.0) ? -1.0 : 1.0,
|
||||
a2 = (ATAN2(b, d) + ATAN2(-sign * c, sign * a)) / 2.0,
|
||||
cos = COS(a2),
|
||||
sin = SIN(a2);
|
||||
|
||||
#define rotate_scale(a, b, c, d) \
|
||||
var sign = (a * d < 0.0 || b * c > 0.0) ? -1.0 : 1.0;\
|
||||
a1 = (ATAN2(sign * b, sign * a) + ATAN2(-c, d)) / 2.0,\
|
||||
cos = COS(a1),\
|
||||
sin = SIN(a1);\
|
||||
\
|
||||
if (cos == 0)\
|
||||
{\
|
||||
sx = b / sin;\
|
||||
sy = -c / sin;\
|
||||
}\
|
||||
else if (sin == 0)\
|
||||
{\
|
||||
sx = a / cos;\
|
||||
sy = d / cos;\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
abs_cos = ABS(cos);\
|
||||
abs_sin = ABS(sin);\
|
||||
\
|
||||
sx = (abs_cos * a / cos + abs_sin * b / sin) / (abs_cos + abs_sin);\
|
||||
sy = (abs_cos * d / cos + abs_sin * -c / sin) / (abs_cos + abs_sin);\
|
||||
}\
|
||||
if (cos === 0)
|
||||
{
|
||||
sx = -c / sin;
|
||||
sy = b / sin;
|
||||
}
|
||||
else if (sin === 0)
|
||||
{
|
||||
sx = a / cos;
|
||||
sy = d / cos;
|
||||
}
|
||||
else
|
||||
{
|
||||
abs_cos = ABS(cos);
|
||||
abs_sin = ABS(sin);
|
||||
|
||||
sx = (abs_cos * a / cos + abs_sin * -c / sin) / (abs_cos + abs_sin);
|
||||
sy = (abs_cos * d / cos + abs_sin * b / sin) / (abs_cos + abs_sin);
|
||||
}
|
||||
};
|
||||
|
||||
var rotate_scale = function(a, b, c, d)
|
||||
{
|
||||
var sign = (a * d < 0.0 || b * c > 0.0) ? -1.0 : 1.0;
|
||||
a1 = (ATAN2(sign * b, sign * a) + ATAN2(-c, d)) / 2.0,
|
||||
cos = COS(a1),
|
||||
sin = SIN(a1);
|
||||
|
||||
if (cos === 0)
|
||||
{
|
||||
sx = b / sin;
|
||||
sy = -c / sin;
|
||||
}
|
||||
else if (sin === 0)
|
||||
{
|
||||
sx = a / cos;
|
||||
sy = d / cos;
|
||||
}
|
||||
else
|
||||
{
|
||||
abs_cos = ABS(cos);
|
||||
abs_sin = ABS(sin);
|
||||
|
||||
sx = (abs_cos * a / cos + abs_sin * b / sin) / (abs_cos + abs_sin);
|
||||
sy = (abs_cos * d / cos + abs_sin * -c / sin) / (abs_cos + abs_sin);
|
||||
}
|
||||
};
|
||||
|
||||
function eigen(anAffineTransform)
|
||||
{
|
||||
alert("IMPLEMENT ME!");
|
||||
CPLog.warn("Unimplemented function: eigen");
|
||||
}
|
||||
|
||||
|
||||
@@ -393,20 +504,20 @@ CGContextConcatCTM = function(aContext, anAffineTransform)
|
||||
a2 = 0.0;
|
||||
|
||||
// Detect the simple case of just scaling.
|
||||
if (b == 0.0 && c == 0.0)
|
||||
if (b === 0.0 && c === 0.0)
|
||||
{
|
||||
sx = a;
|
||||
sy = d;
|
||||
}
|
||||
|
||||
// a scale followed by a rotate
|
||||
else if (a * b == -c * d)
|
||||
else if (a * b === -c * d)
|
||||
{
|
||||
scale_rotate(a, b, c, d)
|
||||
}
|
||||
|
||||
// rotate, then scale.
|
||||
else if (a * c == -b * d)
|
||||
else if (a * c === -b * d)
|
||||
{
|
||||
rotate_scale(a, b, c, d)
|
||||
}
|
||||
@@ -450,6 +561,7 @@ CGContextConcatCTM = function(aContext, anAffineTransform)
|
||||
function CGContextDrawImage(aContext, aRect, anImage)
|
||||
{
|
||||
aContext.drawImage(anImage._image, _CGRectGetMinX(aRect), _CGRectGetMinY(aRect), _CGRectGetWidth(aRect), _CGRectGetHeight(aRect));
|
||||
aContext.hasPath = NO;
|
||||
}
|
||||
|
||||
function to_string(aColor)
|
||||
@@ -469,6 +581,7 @@ function CGContextDrawLinearGradient(aContext, aGradient, aStartPoint, anEndPoin
|
||||
|
||||
aContext.fillStyle = linearGradient;
|
||||
aContext.fill();
|
||||
aContext.hasPath = NO;
|
||||
}
|
||||
|
||||
function CGBitmapGraphicsContextCreate()
|
||||
@@ -478,5 +591,8 @@ function CGBitmapGraphicsContextCreate()
|
||||
|
||||
context.DOMElement = DOMElement;
|
||||
|
||||
// canvas gives us no way to query whether the path is empty or not, so we have to track it ourselves
|
||||
context.hasPath = NO;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ kCGPathElementAddArcToPoint = 6;
|
||||
*/
|
||||
function CGPathCreateMutable()
|
||||
{
|
||||
return { count:0, start:NULL, current:NULL, elements:[] };
|
||||
return { count:0, start:_CGPointMake(0, 0), current:_CGPointMake(0, 0), elements:[] };
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -101,7 +101,7 @@ function CGPathAddArc(aPath, aTransform, x, y, aRadius, aStartAngle, anEndAngle,
|
||||
// Angles that equal "modulo" 2 pi return as equal after transforming them,
|
||||
// so we have to make sure to make them different again if they were different
|
||||
// to start out with. It's the difference between no circle and a full circle.
|
||||
if (anEndAngle == aStartAngle && oldEndAngle != oldStartAngle)
|
||||
if (anEndAngle === aStartAngle && oldEndAngle != oldStartAngle)
|
||||
if (oldStartAngle > oldEndAngle)
|
||||
anEndAngle = anEndAngle - PI2;
|
||||
else
|
||||
@@ -112,7 +112,30 @@ function CGPathAddArc(aPath, aTransform, x, y, aRadius, aStartAngle, anEndAngle,
|
||||
aRadius = SQRT(aRadius.width * aRadius.width + aRadius.height * aRadius.height);
|
||||
}
|
||||
|
||||
aPath.current = _CGPointMake(x + aRadius * COS(anEndAngle), y + aRadius * SIN(anEndAngle));
|
||||
/*
|
||||
From the Cocoa docs:
|
||||
|
||||
If the specified path already contains a subpath, Quartz implicitly adds a line connecting the subpath’s current point to the beginning of the arc. If the path is empty, Quartz creates a new subpath with a starting point set to the starting point of the arc.
|
||||
|
||||
The ending point of the arc becomes the new current point of the path.
|
||||
*/
|
||||
var arcEndX = x + aRadius * COS(anEndAngle),
|
||||
arcEndY = y + aRadius * SIN(anEndAngle);
|
||||
|
||||
if (aPath.count)
|
||||
{
|
||||
if (aPath.current.x !== arcEndX || aPath.current.y !== arcEndY)
|
||||
CGPathAddLineToPoint(aPath, aTransform, arcEndX, arcEndY);
|
||||
}
|
||||
else
|
||||
{
|
||||
var arcStartX = x + aRadius * COS(aStartAngle),
|
||||
arcStartY = y + aRadius * SIN(aStartAngle);
|
||||
|
||||
aPath.start = _CGPointMake(arcStartX, arcStartY);
|
||||
}
|
||||
|
||||
aPath.current = _CGPointMake(arcEndX, arcEndY);
|
||||
aPath.elements[aPath.count++] = { type:kCGPathElementAddArc, x:x, y:y, radius:aRadius, startAngle:aStartAngle, endAngle:anEndAngle, clockwise:isClockwise };
|
||||
}
|
||||
|
||||
@@ -127,6 +150,21 @@ function CGPathAddArcToPoint(aPath, aTransform, x1, y1, x2, y2, aRadius)
|
||||
p2 = _CGPointApplyAffineTransform(p2, aTransform);
|
||||
}
|
||||
|
||||
/*
|
||||
From the Cocoa docs:
|
||||
|
||||
If the current point and the first tangent point of the arc (the starting point) are not equal, Quartz appends a straight line segment from the current point to the first tangent point.
|
||||
|
||||
The ending point of the arc becomes the new current point of the path.
|
||||
*/
|
||||
if (aPath.count)
|
||||
{
|
||||
if (aPath.current.x !== p1.x || aPath.current.y !== p1.y)
|
||||
CGPathAddLineToPoint(aPath, aTransform, p1.x, p1.y);
|
||||
}
|
||||
else
|
||||
aPath.start = p1;
|
||||
|
||||
aPath.current = p2;
|
||||
aPath.elements[aPath.count++] = { type:kCGPathElementAddArcToPoint, p1x:p1.x, p1y:p1.y, p2x:p2.x, p2y:p2.y, radius:aRadius };
|
||||
}
|
||||
@@ -144,8 +182,8 @@ function CGPathAddCurveToPoint(aPath, aTransform, cp1x, cp1y, cp2x, cp2y, x, y)
|
||||
end = _CGPointApplyAffineTransform(end, aTransform);
|
||||
}
|
||||
|
||||
aPath.current = end;
|
||||
aPath.elements[aPath.count++] = { type:kCGPathElementAddCurveToPoint, cp1x:cp1.x, cp1y:cp1.y, cp2x:cp2.x, cp2y:cp2.y, x:end.x, y:end.y };
|
||||
aPath.current = end;
|
||||
aPath.elements[aPath.count++] = { type:kCGPathElementAddCurveToPoint, cp1x:cp1.x, cp1y:cp1.y, cp2x:cp2.x, cp2y:cp2.y, x:end.x, y:end.y };
|
||||
}
|
||||
|
||||
function CGPathAddLines(aPath, aTransform, points, count)
|
||||
@@ -264,21 +302,23 @@ function CGPathAddRects(aPath, aTransform, rects, count)
|
||||
|
||||
function CGPathMoveToPoint(aPath, aTransform, x, y)
|
||||
{
|
||||
var point = _CGPointMake(x, y),
|
||||
count = aPath.count;
|
||||
var point = _CGPointMake(x, y);
|
||||
|
||||
if (aTransform != NULL)
|
||||
point = _CGPointApplyAffineTransform(point, aTransform);
|
||||
|
||||
aPath.start = point;
|
||||
aPath.current = point;
|
||||
aPath.start = aPath.current = point;
|
||||
|
||||
var previous = aPath.elements[count - 1];
|
||||
|
||||
if (count != 0 && previous.type == kCGPathElementMoveToPoint)
|
||||
// If the previous op was a move, just update that point
|
||||
if (aPath.count)
|
||||
{
|
||||
previous.x = point.x;
|
||||
previous.y = point.y;
|
||||
var previous = aPath.elements[count - 1];
|
||||
|
||||
if (previous.type === kCGPathElementMoveToPoint)
|
||||
{
|
||||
previous.x = point.x;
|
||||
previous.y = point.y;
|
||||
}
|
||||
}
|
||||
else
|
||||
aPath.elements[aPath.count++] = { type:kCGPathElementMoveToPoint, x:point.x, y:point.y };
|
||||
@@ -290,7 +330,7 @@ function CGPathWithEllipseInRect(aRect)
|
||||
{
|
||||
var path = CGPathCreateMutable();
|
||||
|
||||
if (_CGRectGetWidth(aRect) == _CGRectGetHeight(aRect))
|
||||
if (_CGRectGetWidth(aRect) === _CGRectGetHeight(aRect))
|
||||
CGPathAddArc(path, nil, _CGRectGetMidX(aRect), _CGRectGetMidY(aRect), _CGRectGetWidth(aRect) / 2.0, 0.0, 2 * PI, YES);
|
||||
else
|
||||
{
|
||||
@@ -362,15 +402,17 @@ function CGPathCloseSubpath(aPath)
|
||||
var count = aPath.count;
|
||||
|
||||
// Don't bother closing this subpath if there aren't any current elements, or the last element already closed the subpath.
|
||||
if (count == 0 || aPath.elements[count - 1].type == kCGPathElementCloseSubpath)
|
||||
if (count === 0 || aPath.elements[count - 1].type === kCGPathElementCloseSubpath)
|
||||
return;
|
||||
|
||||
// After closing, the current point is the previous path's starting point
|
||||
aPath.current = _CGPointCreateCopy(aPath.start);
|
||||
aPath.elements[aPath.count++] = { type:kCGPathElementCloseSubpath, points:[aPath.start] };
|
||||
}
|
||||
|
||||
function CGPathEqualToPath(aPath, anotherPath)
|
||||
{
|
||||
if (aPath == anotherPath)
|
||||
if (aPath === anotherPath)
|
||||
return YES;
|
||||
|
||||
if (aPath.count != anotherPath.count || !_CGPointEqualToPoint(aPath.start, anotherPath.start) || !_CGPointEqualToPoint(aPath.current, anotherPath.current))
|
||||
@@ -387,7 +429,7 @@ function CGPathEqualToPath(aPath, anotherPath)
|
||||
if (element.type != anotherElement.type)
|
||||
return NO;
|
||||
|
||||
if ((element.type == kCGPathElementAddArc || element.type == kCGPathElementAddArcToPoint) &&
|
||||
if ((element.type === kCGPathElementAddArc || element.type === kCGPathElementAddArcToPoint) &&
|
||||
element.radius != anotherElement.radius)
|
||||
return NO;
|
||||
|
||||
@@ -408,7 +450,7 @@ function CGPathGetCurrentPoint(aPath)
|
||||
|
||||
function CGPathIsEmpty(aPath)
|
||||
{
|
||||
return !aPath || aPath.count == 0;
|
||||
return !aPath || aPath.count === 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -438,7 +480,7 @@ function CGPathGetBoundingBox(aPath)
|
||||
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.
|
||||
// This won't work for CGPathGetBoundingBox.
|
||||
switch (element.type)
|
||||
{
|
||||
case kCGPathElementAddLineToPoint:
|
||||
|
||||
@@ -32,11 +32,13 @@
|
||||
[points addObject:CGPointMake(midX, minY)];
|
||||
|
||||
[self lockFocus];
|
||||
|
||||
var context = [[CPGraphicsContext currentContext] graphicsPort];
|
||||
CGContextSetLineWidth(context, 2);
|
||||
CGContextSetStrokeColor(context, [CPColor blueColor]);
|
||||
|
||||
// test CGContextAddLines
|
||||
CGContextBeginPath(context);
|
||||
CGContextAddLines(context, points, NULL);
|
||||
|
||||
// test CGContextAddQuadCurveToPoint
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -12,10 +12,7 @@
|
||||
@implementation AppController : CPObject
|
||||
{
|
||||
CPView contentView;
|
||||
CPTextField label1;
|
||||
CPTextField label2;
|
||||
MyView myView;
|
||||
CPImageView view2;
|
||||
CPImage patternImage1;
|
||||
BOOL patternImage1Loaded;
|
||||
CPImage patternImage2;
|
||||
@@ -28,11 +25,15 @@
|
||||
theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask];
|
||||
|
||||
contentView = [theWindow contentView];
|
||||
label1 = [CPTextField labelWithTitle:@"Dynamically drawn"];
|
||||
label2 = [CPTextField labelWithTitle:@"Screen capture from IE before COORD fix, notice the fuzziness in the pattern"];
|
||||
|
||||
var label1 = [CPTextField labelWithTitle:@"Dynamically drawn"],
|
||||
label2 = [CPTextField labelWithTitle:@"Screen capture from IE before COORD fix, notice the fuzziness in the pattern"];
|
||||
|
||||
patternImage1 = [[CPImage alloc] initWithContentsOfFile:[[CPBundle mainBundle] pathForResource:@"help.png"] size:CGSizeMake(21, 22)];
|
||||
view2 = [[CPImageView alloc] initWithFrame:CGRectMake(x, 210, 200, 200)];
|
||||
img2 = [[CPImage alloc] initWithContentsOfFile:[[CPBundle mainBundle] pathForResource:@"bad.png"] size:CGSizeMake(200, 200)];
|
||||
|
||||
var view2 = [[CPImageView alloc] initWithFrame:CGRectMake(x, 210, 200, 200)],
|
||||
img2 = [[CPImage alloc] initWithContentsOfFile:[[CPBundle mainBundle] pathForResource:@"bad.png"] size:CGSizeMake(200, 200)];
|
||||
|
||||
patternImage2 = [[CPImage alloc] initWithContentsOfFile:[[CPBundle mainBundle] pathForResource:@"pattern.gif"] size:CGSizeMake(56, 32)];
|
||||
|
||||
var fillColor1 = [CPColor colorWithPatternImage:patternImage1],
|
||||
@@ -48,6 +49,11 @@
|
||||
[label2 setFrameOrigin:CGPointMake(x, CGRectGetMaxY([myView frame]) + 20)];
|
||||
[view2 setFrameOrigin:CGPointMake(x, CGRectGetMaxY([label2 frame]) + 5)];
|
||||
|
||||
var label3 = [CPTextField labelWithTitle:@"Pattern fill with rendered path"];
|
||||
[label3 setFrameOrigin:CGPointMake(300, 20)];
|
||||
|
||||
var patternView = [[PatternView alloc] initWithFrame:CGRectMake(300, CGRectGetMaxY([label3 frame]) + 5, 200, 200)];
|
||||
|
||||
// Pattern images MUST be loaded before they are used, so we have to use a load delegate
|
||||
// for each image and draw only when we have them all.
|
||||
if ([patternImage1 loadStatus] === CPImageLoadStatusCompleted)
|
||||
@@ -69,6 +75,13 @@
|
||||
if (patternImage1Loaded && patternImage2Loaded)
|
||||
[self addSubviews];
|
||||
|
||||
[contentView addSubview:label1];
|
||||
[contentView addSubview:label2];
|
||||
[contentView addSubview:label3];
|
||||
[contentView addSubview:myView];
|
||||
[contentView addSubview:view2];
|
||||
[contentView addSubview:patternView];
|
||||
|
||||
[theWindow orderFront:self];
|
||||
|
||||
// Uncomment the following line to turn on the standard menu bar.
|
||||
@@ -83,15 +96,7 @@
|
||||
patternImage2Loaded = YES;
|
||||
|
||||
if (patternImage1Loaded && patternImage2Loaded)
|
||||
[self addSubviews];
|
||||
}
|
||||
|
||||
- (void)addSubviews
|
||||
{
|
||||
[contentView addSubview:label1];
|
||||
[contentView addSubview:label2];
|
||||
[contentView addSubview:myView];
|
||||
[contentView addSubview:view2];
|
||||
[myView setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -117,25 +122,69 @@
|
||||
|
||||
- (void)drawRect:(CGRect)dirtyRect
|
||||
{
|
||||
var context = [[CPGraphicsContext currentContext] graphicsPort];
|
||||
var context = [[CPGraphicsContext currentContext] graphicsPort],
|
||||
bounds = [self bounds];
|
||||
|
||||
CGContextSetFillColor(context, fillColor1);
|
||||
CGContextFillRect(context, [self bounds]);
|
||||
|
||||
CGContextSetFillColor(context, [CPColor yellowColor]);
|
||||
CGContextFillEllipseInRect(context, CGRectInset([self bounds], 40, 40));
|
||||
CGContextFillEllipseInRect(context, CGRectInset(bounds, 40, 40));
|
||||
|
||||
CGContextSetStrokeColor(context, [CPColor blueColor]);
|
||||
CGContextStrokeRect(context, CGRectInset([self bounds], 0.5, 0.5));
|
||||
CGContextStrokeRect(context, CGRectInset(bounds, 0.5, 0.5));
|
||||
|
||||
CGContextSetStrokeColor(context, [CPColor redColor]);
|
||||
CGContextStrokeEllipseInRect(context, CGRectInset([self bounds], 20.5, 20.5));
|
||||
CGContextStrokeEllipseInRect(context, CGRectInset(bounds, 20.5, 20.5));
|
||||
|
||||
CGContextSetStrokeColor(context, [CPColor greenColor]);
|
||||
CGContextStrokeRect(context, CGRectInset([self bounds], 30.5, 30.5));
|
||||
CGContextStrokeRect(context, CGRectInset(bounds, 30.5, 30.5));
|
||||
|
||||
CGContextSetFillColor(context, fillColor2);
|
||||
CGContextFillEllipseInRect(context, CGRectInset([self bounds], 50, 50));
|
||||
CGContextFillEllipseInRect(context, CGRectInset(bounds, 50, 50));
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation PatternView : CPView
|
||||
|
||||
- (void)drawRect:(CGRect)dirtyRect
|
||||
{
|
||||
var context = [[CPGraphicsContext currentContext] graphicsPort],
|
||||
path = CGPathCreateMutable();
|
||||
|
||||
CGPathMoveToPoint(path, NULL, 0.0, 40.0);
|
||||
CGPathAddLineToPoint(path, NULL, 26.9, 36.0);
|
||||
CGPathAddCurveToPoint(path, NULL, 31.7, 36.0, 36.0, 32.1, 36.0, 27.3);
|
||||
CGPathAddLineToPoint(path, NULL, 40.0, 0.0);
|
||||
CGPathAddLineToPoint(path, NULL, 11.8, 3.0);
|
||||
CGPathAddCurveToPoint(path, NULL, 7.0, 3.0, 3.0, 6.9, 3.0, 11.7);
|
||||
CGPathAddLineToPoint(path, NULL, 0.0, 40.0);
|
||||
CGPathCloseSubpath(path);
|
||||
|
||||
var patternContext = CGContextCreatePatternContext(context, CGSizeMake(50, 70));
|
||||
|
||||
CGContextSetFillColor(patternContext, [CPColor colorWithRed:188 / 255 green:222 / 255 blue:178 / 255 alpha:1.0]);
|
||||
|
||||
CGContextAddPath(patternContext, path);
|
||||
CGContextFillPath(patternContext);
|
||||
|
||||
CGContextSetLineWidth(patternContext, 0.8);
|
||||
CGContextSetStrokeColor(patternContext, [CPColor colorWithRed:0 green:156 / 255 blue:86 / 255 alpha:1.0]);
|
||||
CGContextSetLineJoin(patternContext, "miter");
|
||||
CGContextSetMiterLimit(patternContext, 4.0);
|
||||
|
||||
CGContextAddPath(patternContext, path);
|
||||
CGContextStrokePath(patternContext);
|
||||
|
||||
var bounds = [self bounds];
|
||||
|
||||
CGContextSetFillPattern(context, patternContext);
|
||||
CGContextFillRect(context, bounds);
|
||||
|
||||
CGContextSetStrokeColor(context, [CPColor blueColor]);
|
||||
CGContextStrokeRect(context, CGRectInset(bounds, 0.5, 0.5));
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user