PageRenderTime 26ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 1ms

/Dependencies/UIGlossyButton/UIGlossyButton.m

https://gitlab.com/Mr.Tomato/VideoEffects
Objective C | 528 lines | 426 code | 82 blank | 20 comment | 45 complexity | 54b7cd0861a2e881594888e875a4d6da MD5 | raw file
  1. //
  2. // UIButton+Effects.m
  3. // fwMeCard
  4. //
  5. // Created by Water Lou on 6/1/11.
  6. // Copyright 2011 First Water Tech Ltd. All rights reserved.
  7. //
  8. #import "UIGlossyButton.h"
  9. static void *enabledObserverContext = &enabledObserverContext;
  10. static void *highlightedObserverContext = &highlightedObserverContext;
  11. @implementation UIButton(UIGlossyButton)
  12. - (void) useWhiteLabel : (BOOL) dimOnClickedOrDisabled {
  13. [self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  14. UIColor *dimColor = nil;
  15. if (dimOnClickedOrDisabled) dimColor = [UIColor lightGrayColor];
  16. [self setTitleColor:dimColor forState:UIControlStateDisabled];
  17. [self setTitleColor:dimColor forState:UIControlStateHighlighted];
  18. }
  19. - (void) useBlackLabel : (BOOL) dimOnClickedOrDisabled {
  20. [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
  21. UIColor *dimColor = nil;
  22. if (dimOnClickedOrDisabled) dimColor = [UIColor darkGrayColor];
  23. [self setTitleColor:dimColor forState:UIControlStateDisabled];
  24. [self setTitleColor:dimColor forState:UIControlStateHighlighted];
  25. }
  26. @end
  27. @implementation UIColor(UIGlossyButton)
  28. + (UIColor*) doneButtonColor {
  29. return [UIColor colorWithRed:34.0f/255.0f green:96.0f/255.0f blue:221.0f/255.0f alpha:1.0f]; // DONE
  30. }
  31. + (UIColor*) navigationBarButtonColor {
  32. return [UIColor colorWithRed:72.0f/255.0f green:106.0f/255.0f blue:154.0f/255.0f alpha:1.0f];
  33. }
  34. @end
  35. #pragma =================================================
  36. #pragma =================================================
  37. #pragma =================================================
  38. @interface UIGlossyButton() {
  39. // data to create gradient of the button
  40. const CGFloat *_backgroundGradient;
  41. const CGFloat *_locations;
  42. NSInteger _numberOfColorsInGradient;
  43. }
  44. // main draw routine, not including stroke the outer path
  45. - (void) drawTintColorButton : (CGContextRef)context buttonTintColor : (UIColor *) buttonTintColor isSelected : (BOOL) isSelected;
  46. - (void) strokeButton : (CGContextRef)context color : (UIColor *)color isSelected : (BOOL) isSelected;
  47. @end
  48. @implementation UIGlossyButton
  49. #pragma lifecycle
  50. + (void) initialize
  51. {
  52. // default appearance
  53. id appearance = [[self class] appearance];
  54. [appearance setButtonCornerRadius: 4.0f];
  55. [appearance setInnerBorderWidth: 1.0f];
  56. [appearance setButtonBorderWidth: 1.0f];
  57. [appearance setBackgroundOpacity: 1.0f];
  58. [appearance setGradientType: kUIGlossyButtonGradientTypeLinearSmoothStandard];
  59. }
  60. - (void) setupSelf {
  61. [self addObserver:self forKeyPath:@"highlighted" options:0 context:highlightedObserverContext];
  62. [self addObserver:self forKeyPath:@"enabled" options:0 context:enabledObserverContext];
  63. }
  64. - (id) initWithCoder:(NSCoder *)aDecoder {
  65. self = [super initWithCoder:aDecoder];
  66. if (self) {
  67. [self setupSelf];
  68. }
  69. return self;
  70. }
  71. - (id) initWithFrame:(CGRect)frame {
  72. self = [super initWithFrame:frame];
  73. if (self) {
  74. [self setupSelf];
  75. }
  76. return self;
  77. }
  78. -(void) dealloc {
  79. [self removeObserver:self forKeyPath:@"highlighted"];
  80. [self removeObserver:self forKeyPath:@"enabled"];
  81. }
  82. #pragma mark -
  83. /* graident that will be used to fill on top of the button for 3D effect */
  84. - (void) setGradientType : (UIGlossyButtonGradientType) type {
  85. switch (type) {
  86. case kUIGlossyButtonGradientTypeLinearSmoothStandard:
  87. {
  88. static const CGFloat g0[] = {0.5, 1.0, 0.35, 1.0};
  89. _backgroundGradient = g0;
  90. _locations = nil;
  91. _numberOfColorsInGradient = 2;
  92. }
  93. break;
  94. case kUIGlossyButtonGradientTypeLinearSmoothExtreme:
  95. {
  96. static const CGFloat g0[] = {0.8, 1.0, 0.2, 1.0};
  97. _backgroundGradient = g0;
  98. _locations = nil;
  99. _numberOfColorsInGradient = 2;
  100. }
  101. break;
  102. case kUIGlossyButtonGradientTypeLinearSmoothBrightToNormal:
  103. {
  104. static const CGFloat g0[] = {0.9, 1.0, 0.5, 1.0, 0.5, 1.0};
  105. static const CGFloat l0[] = {0.0, 0.7, 1.0};
  106. _backgroundGradient = g0;
  107. _locations = l0;
  108. _numberOfColorsInGradient = 3;
  109. }
  110. break;
  111. case kUIGlossyButtonGradientTypeLinearGlossyStandard:
  112. {
  113. static const CGFloat g0[] = {0.7, 1.0, 0.6, 1.0, 0.5, 1.0, 0.45, 1.0};
  114. static const CGFloat l0[] = {0.0, 0.47, 0.53, 1.0};
  115. _backgroundGradient = g0;
  116. _locations = l0;
  117. _numberOfColorsInGradient = 4;
  118. }
  119. break;
  120. case kUIGlossyButtonGradientTypeSolid:
  121. {
  122. // simplify the code, we create a gradient with one color
  123. static const CGFloat g0[] = {0.5, 1.0, 0.5, 1.0};
  124. _backgroundGradient = g0;
  125. _locations = nil;
  126. _numberOfColorsInGradient = 2;
  127. }
  128. break;
  129. default:
  130. break;
  131. }
  132. }
  133. - (UIBezierPath *) pathForButton : (CGFloat) inset {
  134. CGFloat radius = _buttonCornerRadius - inset;
  135. if (radius<0.0) radius = 0.0;
  136. CGRect rr = UIEdgeInsetsInsetRect(self.bounds, _buttonInsets);
  137. return [UIBezierPath bezierPathWithRoundedRect:CGRectInset(rr, inset, inset) cornerRadius:radius];
  138. }
  139. - (void)drawRect:(CGRect)rect {
  140. UIColor *color = _buttonTintColor;
  141. if (![self isEnabled]) {
  142. if (_disabledColor) color = _disabledColor;
  143. else color = [UIColor lightGrayColor];
  144. }
  145. if (color==nil) color = [UIColor whiteColor];
  146. // if the background is transparent, we draw on a image
  147. // and copy the image to the context with alpha
  148. BOOL drawOnImage = _backgroundOpacity<1.0;
  149. if (drawOnImage) {
  150. UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0f);
  151. }
  152. CGContextRef ref = UIGraphicsGetCurrentContext();
  153. BOOL isSelected = [self isHighlighted];
  154. CGContextSaveGState(ref);
  155. if (_buttonBorderWidth>0.0) {
  156. UIColor *color;
  157. if ([self isEnabled]) color = _borderColor;
  158. else {
  159. color = _disabledBorderColor;
  160. if (color==nil) color = _borderColor;
  161. }
  162. if (color == nil) color = [UIColor darkGrayColor];
  163. [self strokeButton : ref color : color isSelected: isSelected];
  164. }
  165. [self drawTintColorButton : ref buttonTintColor : color isSelected: isSelected];
  166. CGContextRestoreGState(ref);
  167. if (drawOnImage) {
  168. UIImage *i = UIGraphicsGetImageFromCurrentImageContext();
  169. UIGraphicsEndImageContext();
  170. [i drawAtPoint:CGPointZero blendMode:kCGBlendModeNormal alpha:_backgroundOpacity];
  171. }
  172. [super drawRect: rect];
  173. }
  174. #pragma mark KVO
  175. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
  176. {
  177. if (context==enabledObserverContext || context==highlightedObserverContext) {
  178. [self setNeedsDisplay];
  179. }
  180. else {
  181. [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
  182. }
  183. }
  184. #pragma -
  185. - (void) strokeButton : (CGContextRef)context color : (UIColor *)color isSelected : (BOOL) isSelected {
  186. switch (_strokeType) {
  187. case kUIGlossyButtonStrokeTypeNone:
  188. break;
  189. case kUIGlossyButtonStrokeTypeSolid:
  190. // simple solid border
  191. CGContextAddPath(context, [self pathForButton : 0.0f].CGPath);
  192. [color setFill];
  193. CGContextFillPath(context);
  194. break;
  195. case kUIGlossyButtonStrokeTypeGradientFrame:
  196. // solid border with gradient outer frame
  197. {
  198. CGRect rect = self.bounds;
  199. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
  200. CGFloat strokeComponents[] = {
  201. 0.25f, 1.0f, 1.0f, 1.0f
  202. };
  203. UIBezierPath *outerPath = [self pathForButton : 0.0f];
  204. CGContextAddPath(context, outerPath.CGPath);
  205. [color setFill];
  206. CGContextFillPath(context);
  207. // stroke the gradient in 1 pixels using overlay so that still keep the stroke color
  208. CGContextSaveGState(context);
  209. CGContextAddPath(context, outerPath.CGPath);
  210. CGContextAddPath(context, [self pathForButton : 1.0f].CGPath);
  211. CGContextEOClip(context);
  212. CGContextSetBlendMode(context, kCGBlendModeOverlay);
  213. CGGradientRef strokeGradient = CGGradientCreateWithColorComponents(colorSpace, strokeComponents, NULL, 2);
  214. CGContextDrawLinearGradient(context, strokeGradient, CGPointMake(0, CGRectGetMinY(rect)), CGPointMake(0,CGRectGetMaxY(rect)), 0);
  215. CGGradientRelease(strokeGradient);
  216. CGColorSpaceRelease(colorSpace);
  217. CGContextRestoreGState(context);
  218. }
  219. break;
  220. case kUIGlossyButtonStrokeTypeInnerBevelDown:
  221. {
  222. CGContextSaveGState(context);
  223. CGPathRef path = [self pathForButton: 0.0f].CGPath;
  224. CGContextAddPath(context, path);
  225. CGContextClip(context);
  226. [[UIColor colorWithWhite:0.9f alpha:1.0f] setFill];
  227. CGContextAddPath(context, path);
  228. CGContextFillPath(context);
  229. CGFloat highlightWidth = _buttonBorderWidth / 4.0f;
  230. if (highlightWidth<0.5f) highlightWidth = 0.5f;
  231. else if (highlightWidth>2.0f) highlightWidth = 2.0f;
  232. CGPathRef innerPath = [self pathForButton: highlightWidth].CGPath;
  233. CGContextTranslateCTM(context, 0.0f, -highlightWidth);
  234. [color setFill];
  235. CGContextAddPath(context, innerPath);
  236. CGContextFillPath(context);
  237. CGContextRestoreGState(context);
  238. }
  239. break;
  240. case kUIGlossyButtonStrokeTypeBevelUp:
  241. {
  242. CGRect rect = self.bounds;
  243. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
  244. const CGFloat *strokeComponents;
  245. const CGFloat *l0;
  246. if (_invertGraidentOnSelected && isSelected) {
  247. const CGFloat s[] = {0.2, 1, 0.5, 1, 0.6, 1};
  248. const CGFloat l[] = {0.0, 0.1, 1.0};
  249. strokeComponents = s; l0 = l;
  250. }
  251. else {
  252. const CGFloat s[] = {0.9, 1, 0.5, 1, 0.2, 1};
  253. const CGFloat l[] = {0.0, 0.1, 1.0};
  254. strokeComponents = s; l0 = l;
  255. }
  256. CGContextAddPath(context, [self pathForButton : 0.0f].CGPath);
  257. CGContextClip(context);
  258. CGGradientRef strokeGradient = CGGradientCreateWithColorComponents(colorSpace, strokeComponents, l0, 3);
  259. CGContextDrawLinearGradient(context, strokeGradient, CGPointMake(0, CGRectGetMinY(rect)), CGPointMake(0,CGRectGetMaxY(rect)), 0);
  260. CGGradientRelease(strokeGradient);
  261. CGColorSpaceRelease(colorSpace);
  262. [color set];
  263. UIRectFillUsingBlendMode(rect, kCGBlendModeOverlay);
  264. CGContextFillPath(context);
  265. }
  266. break;
  267. default:
  268. break;
  269. }
  270. }
  271. - (void) addShading : (CGContextRef) context type : (UIGlossyButtonExtraShadingType)type rect : (CGRect) rect colorSpace : (CGColorSpaceRef) colorSpace {
  272. switch (type) {
  273. case kUIGlossyButtonExtraShadingTypeRounded:
  274. {
  275. CGPathRef shade = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(rect.origin.x, rect.origin.y-_buttonCornerRadius, rect.size.width, _buttonCornerRadius+rect.size.height/2.0) cornerRadius:_buttonCornerRadius].CGPath;
  276. CGContextAddPath(context, shade);
  277. CGContextClip(context);
  278. const CGFloat strokeComponents[4] = {0.80, 1, 0.55, 1};
  279. CGGradientRef strokeGradient = CGGradientCreateWithColorComponents(colorSpace, strokeComponents, NULL, 2);
  280. CGContextDrawLinearGradient(context, strokeGradient, CGPointMake(0, CGRectGetMinY(rect)), CGPointMake(0,rect.origin.y + rect.size.height * 0.7), 0);
  281. CGGradientRelease(strokeGradient);
  282. }
  283. break;
  284. case kUIGlossyButtonExtraShadingTypeAngleLeft:
  285. {
  286. CGRect roundRect = CGRectMake(rect.origin.x-rect.size.width * 2, rect.origin.y - rect.size.height * 3.33, rect.size.width*4.0f, rect.size.height*4.0f);
  287. CGContextAddEllipseInRect(context, roundRect);
  288. CGContextClip(context);
  289. const CGFloat strokeComponents[4] = {0.80, 1, 0.55, 1};
  290. CGGradientRef strokeGradient = CGGradientCreateWithColorComponents(colorSpace, strokeComponents, NULL, 2);
  291. CGContextDrawLinearGradient(context, strokeGradient, CGPointMake(rect.origin.x, rect.origin.y), CGPointMake(rect.origin.x+rect.size.width / 2.0, rect.origin.y + rect.size.height * 0.7), 0);
  292. CGGradientRelease(strokeGradient);
  293. }
  294. break;
  295. case kUIGlossyButtonExtraShadingTypeAngleRight:
  296. {
  297. CGRect roundRect = CGRectMake(rect.origin.x-rect.size.width, rect.origin.y - rect.size.height * 3.33, rect.size.width*4.0f, rect.size.height*4.0f);
  298. CGContextAddEllipseInRect(context, roundRect);
  299. CGContextClip(context);
  300. const CGFloat strokeComponents[4] = {0.80, 1, 0.55, 1};
  301. CGGradientRef strokeGradient = CGGradientCreateWithColorComponents(colorSpace, strokeComponents, NULL, 2);
  302. CGContextDrawLinearGradient(context, strokeGradient, CGPointMake(rect.origin.x+rect.size.width, rect.origin.y), CGPointMake(rect.origin.x+rect.size.width / 2.0, rect.origin.y + rect.size.height * 0.7), 0);
  303. CGGradientRelease(strokeGradient);
  304. }
  305. break;
  306. default:
  307. break;
  308. }
  309. }
  310. - (void) drawTintColorButton : (CGContextRef)context buttonTintColor : (UIColor *) buttonTintColor isSelected : (BOOL) isSelected {
  311. CGRect rect = self.bounds;
  312. CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
  313. if (_innerBorderWidth > 0.0) {
  314. // STROKE GRADIENT
  315. CGContextAddPath(context, [self pathForButton : _buttonBorderWidth].CGPath);
  316. CGContextClip(context);
  317. CGContextSaveGState(context);
  318. const CGFloat strokeComponents[4] = {0.55, 1, 0.40, 1};
  319. CGGradientRef strokeGradient = CGGradientCreateWithColorComponents(colorSpace, strokeComponents, NULL, 2);
  320. CGContextDrawLinearGradient(context, strokeGradient, CGPointMake(0, CGRectGetMinY(rect)), CGPointMake(0,CGRectGetMaxY(rect)), 0);
  321. CGGradientRelease(strokeGradient);
  322. }
  323. // FILL GRADIENT
  324. CGRect fillRect = CGRectInset(rect,_buttonBorderWidth + _innerBorderWidth, _buttonBorderWidth + _innerBorderWidth);
  325. CGContextAddPath(context, [self pathForButton : _buttonBorderWidth + _innerBorderWidth].CGPath);
  326. CGContextClip(context);
  327. CGGradientRef fillGradient = CGGradientCreateWithColorComponents(colorSpace, _backgroundGradient, _locations, _numberOfColorsInGradient);
  328. if (_invertGraidentOnSelected && isSelected) {
  329. CGContextDrawLinearGradient(context, fillGradient, CGPointMake(0, CGRectGetMaxY(fillRect)), CGPointMake(0,CGRectGetMinY(fillRect)), 0);
  330. }
  331. else {
  332. CGContextDrawLinearGradient(context, fillGradient, CGPointMake(0, CGRectGetMinY(fillRect)), CGPointMake(0,CGRectGetMaxY(fillRect)), 0);
  333. }
  334. CGGradientRelease(fillGradient);
  335. if (_extraShadingType != kUIGlossyButtonExtraShadingTypeNone) {
  336. // add additional glossy effect
  337. CGContextSaveGState(context);
  338. CGContextSetBlendMode(context, kCGBlendModeLighten);
  339. [self addShading:context type:_extraShadingType rect:fillRect colorSpace:colorSpace];
  340. CGContextRestoreGState(context);
  341. }
  342. CGColorSpaceRelease(colorSpace);
  343. if (_innerBorderWidth > 0.0) {
  344. CGContextRestoreGState(context);
  345. }
  346. [buttonTintColor set];
  347. UIRectFillUsingBlendMode(rect, kCGBlendModeOverlay);
  348. if (isSelected) {
  349. [[UIColor lightGrayColor] set];
  350. UIRectFillUsingBlendMode(rect, kCGBlendModeMultiply);
  351. }
  352. }
  353. #pragma pre-defined buttons
  354. - (void) setActionSheetButtonWithColor : (UIColor*) color {
  355. self.buttonTintColor = color;
  356. [self setGradientType:kUIGlossyButtonGradientTypeLinearGlossyStandard];
  357. [self.titleLabel setFont: [UIFont boldSystemFontOfSize: 17.0f]];
  358. [self useWhiteLabel: NO];
  359. self.buttonCornerRadius = 8.0f;
  360. self.strokeType = kUIGlossyButtonStrokeTypeGradientFrame;
  361. self.buttonBorderWidth = 3.0;
  362. self.borderColor = [UIColor colorWithWhite:0.2f alpha:0.8f];
  363. [self setNeedsDisplay];
  364. }
  365. - (void) setNavigationButtonWithColor : (UIColor*) color {
  366. self.buttonTintColor = color;
  367. self.disabledBorderColor = [UIColor lightGrayColor];
  368. [self setGradientType:kUIGlossyButtonGradientTypeLinearGlossyStandard];
  369. [self.titleLabel setFont: [UIFont boldSystemFontOfSize: 12.0f]];
  370. [self useWhiteLabel: NO];
  371. [self setTitleColor:[UIColor colorWithWhite:0.5 alpha:1.0] forState:UIControlStateDisabled];
  372. self.buttonCornerRadius = 4.0f;
  373. self.strokeType = kUIGlossyButtonStrokeTypeInnerBevelDown;
  374. self.buttonBorderWidth = 1.0;
  375. self.innerBorderWidth = 0.0;
  376. [self setNeedsDisplay];
  377. }
  378. @end
  379. @implementation UIGNavigationButton
  380. - (UIBezierPath *) pathForButton : (CGFloat) inset {
  381. CGRect bounds = UIEdgeInsetsInsetRect(self.bounds, self.buttonInsets);
  382. CGRect rr = CGRectInset(bounds, inset, inset);
  383. CGFloat radius = self.buttonCornerRadius - inset;
  384. if (radius<0.0) radius = 0.0;
  385. CGFloat arrowWidth = round(bounds.size.height * 0.30);
  386. CGFloat radiusOffset = 0.29289321 * radius;
  387. CGFloat extraHeadInset = 0.01118742 * inset;
  388. if (_leftArrow) {
  389. CGRect rr1 = CGRectMake(arrowWidth+rr.origin.x+extraHeadInset, rr.origin.y, rr.size.width-arrowWidth-extraHeadInset, rr.size.height);
  390. UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rr1 cornerRadius:radius];
  391. [path moveToPoint: CGPointMake(rr.origin.x+extraHeadInset, rr.origin.y + rr.size.height / 2.0)];
  392. [path addLineToPoint:CGPointMake(rr.origin.x+arrowWidth+radiusOffset+extraHeadInset, rr.origin.y+radiusOffset)];
  393. [path addLineToPoint:CGPointMake(rr.origin.x+arrowWidth+radiusOffset+extraHeadInset, rr.origin.y+rr.size.height-radiusOffset)];
  394. [path closePath];
  395. return path;
  396. }
  397. else {
  398. CGRect rr1 = CGRectMake(rr.origin.x, rr.origin.y, rr.size.width-arrowWidth-extraHeadInset, rr.size.height);
  399. UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rr1 cornerRadius:radius];
  400. [path moveToPoint: CGPointMake(rr.origin.x + rr.size.width - extraHeadInset, rr.origin.y + rr.size.height / 2.0)];
  401. [path addLineToPoint:CGPointMake(rr.origin.x+ rr.size.width - arrowWidth - radiusOffset - extraHeadInset, rr.origin.y+rr.size.height-radiusOffset)];
  402. [path addLineToPoint:CGPointMake(rr.origin.x+ rr.size.width - arrowWidth - radiusOffset - extraHeadInset, rr.origin.y+radiusOffset)];
  403. [path closePath];
  404. return path;
  405. }
  406. }
  407. - (CGRect)titleRectForContentRect:(CGRect)contentRect {
  408. CGFloat arrowWidth = round(self.bounds.size.height * 0.30);
  409. if (_leftArrow) {
  410. contentRect.origin.x += arrowWidth; contentRect.size.width -= arrowWidth;
  411. }
  412. else {
  413. contentRect.size.width -= arrowWidth;
  414. }
  415. return [super titleRectForContentRect: contentRect];
  416. }
  417. @end
  418. @implementation UIGBadgeButton
  419. - (void) setupSelf {
  420. [super setupSelf];
  421. _numberOfEdges = 24;
  422. _innerRadiusRatio = 0.75;
  423. }
  424. - (UIBezierPath *) pathForButton : (CGFloat) inset
  425. {
  426. CGRect bounds = UIEdgeInsetsInsetRect(self.bounds, self.buttonInsets);
  427. CGPoint center = CGPointMake(bounds.size.width/2.0, bounds.size.height/2.0);
  428. CGFloat outerRadius = MIN(bounds.size.width, bounds.size.height) / 2.0 - inset;
  429. CGFloat innerRadius = outerRadius * _innerRadiusRatio;
  430. CGFloat angle = M_PI * 2.0 / (_numberOfEdges * 2);
  431. UIBezierPath *path = [UIBezierPath bezierPath];
  432. for (NSInteger cc=0; cc<_numberOfEdges; cc++) {
  433. CGPoint p0 = CGPointMake(center.x + outerRadius * cos(angle * (cc*2)), center.y + outerRadius * sin(angle * (cc*2)));
  434. CGPoint p1 = CGPointMake(center.x + innerRadius * cos(angle * (cc*2+1)), center.y + innerRadius * sin(angle * (cc*2+1)));
  435. if (cc==0) {
  436. [path moveToPoint: p0];
  437. }
  438. else {
  439. [path addLineToPoint: p0];
  440. }
  441. [path addLineToPoint: p1];
  442. }
  443. [path closePath];
  444. return path;
  445. }
  446. @end