123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- #import "SVGRectElement.h"
- #import "SVGElement_ForParser.h" // to resolve Xcode circular dependencies; in long term, parsing SHOULD NOT HAPPEN inside any class whose name starts "SVG" (because those are reserved classes for the SVG Spec)
- #import "SVGHelperUtilities.h"
- @interface SVGRectElement ()
- #if SVGKIT_UIKIT && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_7_0
- void CGPathAddRoundedRect (CGMutablePathRef path, CGRect rect, CGFloat radiusX, CGFloat radiusY);
- #endif
- @end
- @implementation SVGRectElement
- @synthesize transform; // each SVGElement subclass that conforms to protocol "SVGTransformable" has to re-synthesize this to work around bugs in Apple's Objective-C 2.0 design that don't allow @properties to be extended by categories / protocols
- @synthesize x = _x;
- @synthesize y = _y;
- @synthesize width = _width;
- @synthesize height = _height;
- @synthesize rx = _rx;
- @synthesize ry = _ry;
- #if SVGKIT_UIKIT && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_7_0
- // adapted from http://www.cocoanetics.com/2010/02/drawing-rounded-rectangles/
- void CGPathAddRoundedRect (CGMutablePathRef path, CGRect rect, CGFloat radiusX, CGFloat radiusY) {
- CGRect innerRect = CGRectInset(rect, radiusX, radiusY);
-
- CGFloat innerRight = innerRect.origin.x + innerRect.size.width;
- CGFloat right = rect.origin.x + rect.size.width;
- CGFloat innerBottom = innerRect.origin.y + innerRect.size.height;
- CGFloat bottom = rect.origin.y + rect.size.height;
-
- CGFloat innerTop = innerRect.origin.y;
- CGFloat top = rect.origin.y;
- CGFloat innerLeft = innerRect.origin.x;
- CGFloat left = rect.origin.x;
-
- CGPathMoveToPoint(path, NULL, innerLeft, top);
-
- CGPathAddLineToPoint(path, NULL, innerRight, top);
- /** c.f http://stackoverflow.com/a/12152442/153422 */
- CGAffineTransform t = CGAffineTransformConcat( CGAffineTransformMakeScale(1.0, radiusY/radiusX), CGAffineTransformMakeTranslation(innerRight, innerTop));
- CGPathAddArc(path, &t, 0, 0, radiusX, -M_PI_2, 0, false);
-
- CGPathAddLineToPoint(path, NULL, right, innerBottom);
- /** c.f http://stackoverflow.com/a/12152442/153422 */
- t = CGAffineTransformConcat( CGAffineTransformMakeScale(1.0, radiusY/radiusX), CGAffineTransformMakeTranslation(innerRight, innerBottom));
- CGPathAddArc(path, &t, 0, 0, radiusX, 0, M_PI_2, false);
-
- CGPathAddLineToPoint(path, NULL, innerLeft, bottom);
- /** c.f http://stackoverflow.com/a/12152442/153422 */
- t = CGAffineTransformConcat( CGAffineTransformMakeScale(1.0, radiusY/radiusX), CGAffineTransformMakeTranslation(innerLeft, innerBottom));
- CGPathAddArc(path, &t, 0, 0, radiusX, M_PI_2, M_PI, false);
-
- CGPathAddLineToPoint(path, NULL, left, innerTop);
- /** c.f http://stackoverflow.com/a/12152442/153422 */
- t = CGAffineTransformConcat( CGAffineTransformMakeScale(1.0, radiusY/radiusX), CGAffineTransformMakeTranslation(innerLeft, innerTop));
- CGPathAddArc(path, &t, 0, 0, radiusX, M_PI, 3*M_PI_2, false);
-
- CGPathCloseSubpath(path);
- }
- #endif
- - (void)postProcessAttributesAddingErrorsTo:(SVGKParseResult *)parseResult {
- [super postProcessAttributesAddingErrorsTo:parseResult];
-
- if( [[self getAttribute:@"x"] length] > 0 )
- _x = [SVGLength svgLengthFromNSString:[self getAttribute:@"x"]];
-
- if( [[self getAttribute:@"y"] length] > 0 )
- _y = [SVGLength svgLengthFromNSString:[self getAttribute:@"y"]];
-
- if( [[self getAttribute:@"width"] length] > 0 )
- _width = [SVGLength svgLengthFromNSString:[self getAttribute:@"width"]];
-
- if( [[self getAttribute:@"height"] length] > 0 )
- _height = [SVGLength svgLengthFromNSString:[self getAttribute:@"height"]];
-
- if( [[self getAttribute:@"rx"] length] > 0 )
- _rx = [SVGLength svgLengthFromNSString:[self getAttribute:@"rx"]];
-
- if( [[self getAttribute:@"ry"] length] > 0 )
- _ry = [SVGLength svgLengthFromNSString:[self getAttribute:@"ry"]];
- /**
- Create a square OR rounded rectangle as a CGPath
-
- */
- SVGRect r = parseResult.rootOfSVGTree.viewport;
- CGMutablePathRef path = CGPathCreateMutable();
- CGRect rect = CGRectMake([_x pixelsValueWithDimension:r.x], [_y pixelsValueWithDimension:r.y],
- [_width pixelsValueWithDimension:r.width], [_height pixelsValueWithDimension:r.height]);
-
- CGFloat radiusXPixels = _rx != nil ? [_rx pixelsValue] : 0;
- CGFloat radiusYPixels = _ry != nil ? [_ry pixelsValue] : 0;
-
- if( radiusXPixels == 0 && radiusYPixels == 0 )
- {
- CGPathAddRect(path, NULL, rect);
- }
- else
- {
- if( radiusXPixels > 0 && radiusYPixels == 0 ) // if RY unspecified, make it equal to RX
- radiusYPixels = radiusXPixels;
- else if( radiusXPixels == 0 && radiusYPixels > 0 ) // if RX unspecified, make it equal to RY
- radiusXPixels = radiusYPixels;
-
- if( radiusXPixels > CGRectGetWidth(rect) / 2 ) // give RX max value of half rect width
- radiusXPixels = CGRectGetWidth(rect) / 2;
-
- if( radiusYPixels > CGRectGetHeight(rect) / 2 ) // give RY max value of half rect height
- radiusYPixels = CGRectGetHeight(rect) / 2;
-
- CGPathAddRoundedRect(path,
- #if !(SVGKIT_UIKIT && __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_7_0)
- nil,
- #endif
- rect, radiusXPixels, radiusYPixels);
- }
- self.pathForShapeInRelativeCoords = path;
- CGPathRelease(path);
- }
- @end
|