/core/externals/google-toolbox-for-mac/AppKit/GTMNSBezierPath+RoundRect.m

http://macfuse.googlecode.com/ · Objective C · 101 lines · 64 code · 12 blank · 25 comment · 3 complexity · b660e070ec14fbbc994a126102107998 MD5 · raw file

  1. //
  2. // GTMNSBezierPath+RoundRect.h
  3. //
  4. // Category for adding utility functions for creating
  5. // round rectangles.
  6. //
  7. // Copyright 2006-2008 Google Inc.
  8. //
  9. // Licensed under the Apache License, Version 2.0 (the "License"); you may not
  10. // use this file except in compliance with the License. You may obtain a copy
  11. // of the License at
  12. //
  13. // http://www.apache.org/licenses/LICENSE-2.0
  14. //
  15. // Unless required by applicable law or agreed to in writing, software
  16. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  17. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  18. // License for the specific language governing permissions and limitations under
  19. // the License.
  20. //
  21. #import "GTMNSBezierPath+RoundRect.h"
  22. @implementation NSBezierPath (GTMBezierPathRoundRectAdditions)
  23. + (NSBezierPath *)gtm_bezierPathWithRoundRect:(NSRect)rect
  24. cornerRadius:(CGFloat)radius {
  25. NSBezierPath *bezier = [NSBezierPath bezierPath];
  26. [bezier gtm_appendBezierPathWithRoundRect:rect cornerRadius:radius];
  27. return bezier;
  28. }
  29. + (NSBezierPath *)gtm_bezierPathWithRoundRect:(NSRect)rect
  30. topLeftCornerRadius:(CGFloat)radiusTL
  31. topRightCornerRadius:(CGFloat)radiusTR
  32. bottomLeftCornerRadius:(CGFloat)radiusBL
  33. bottomRightCornerRadius:(CGFloat)radiusBR {
  34. NSBezierPath *bezier = [NSBezierPath bezierPath];
  35. [bezier gtm_appendBezierPathWithRoundRect:rect
  36. topLeftCornerRadius:radiusTL
  37. topRightCornerRadius:radiusTR
  38. bottomLeftCornerRadius:radiusBL
  39. bottomRightCornerRadius:radiusBR];
  40. return bezier;
  41. }
  42. - (void)gtm_appendBezierPathWithRoundRect:(NSRect)rect
  43. cornerRadius:(CGFloat)radius {
  44. if (radius > 0.0) {
  45. // Clamp radius to be no larger than half the rect's width or height.
  46. radius = MIN(radius, 0.5 * MIN(rect.size.width, rect.size.height));
  47. [self gtm_appendBezierPathWithRoundRect:rect
  48. topLeftCornerRadius:radius
  49. topRightCornerRadius:radius
  50. bottomLeftCornerRadius:radius
  51. bottomRightCornerRadius:radius];
  52. } else {
  53. // When radius <= 0.0, use plain rectangle.
  54. [self appendBezierPathWithRect:rect];
  55. }
  56. }
  57. - (void)gtm_appendBezierPathWithRoundRect:(NSRect)rect
  58. topLeftCornerRadius:(CGFloat)radiusTL
  59. topRightCornerRadius:(CGFloat)radiusTR
  60. bottomLeftCornerRadius:(CGFloat)radiusBL
  61. bottomRightCornerRadius:(CGFloat)radiusBR {
  62. // Clamp radii to be at least zero. I'd like to clamp both TL+TR and BL+BR to
  63. // be less than the width and TL+BL and TR+BR to be less than the height, but
  64. // what to do if they're not? Do we scale them both evenly?
  65. radiusTL = MAX(0, radiusTL);
  66. radiusTR = MAX(0, radiusTR);
  67. radiusBL = MAX(0, radiusBL);
  68. radiusBR = MAX(0, radiusBR);
  69. if (!NSIsEmptyRect(rect)) {
  70. NSPoint topLeft = NSMakePoint(NSMinX(rect), NSMaxY(rect));
  71. NSPoint topRight = NSMakePoint(NSMaxX(rect), NSMaxY(rect));
  72. NSPoint bottomRight = NSMakePoint(NSMaxX(rect), NSMinY(rect));
  73. [self moveToPoint:NSMakePoint(NSMidX(rect), NSMaxY(rect))];
  74. [self appendBezierPathWithArcFromPoint:topLeft
  75. toPoint:rect.origin
  76. radius:radiusTL];
  77. [self appendBezierPathWithArcFromPoint:rect.origin
  78. toPoint:bottomRight
  79. radius:radiusBL];
  80. [self appendBezierPathWithArcFromPoint:bottomRight
  81. toPoint:topRight
  82. radius:radiusBR];
  83. [self appendBezierPathWithArcFromPoint:topRight
  84. toPoint:topLeft
  85. radius:radiusTR];
  86. [self closePath];
  87. }
  88. }
  89. @end