[ios] Fix clipped bounds calculation for gradients

Fixes https://github.com/react-native-community/react-native-svg/issues/738
This commit is contained in:
Mikael Sand
2018-09-01 13:49:13 +03:00
parent a1097b8594
commit 11a57526fc
5 changed files with 18 additions and 16 deletions
+1 -1
View File
@@ -35,6 +35,6 @@
* be clipped. * be clipped.
* @abstract * @abstract
*/ */
- (void)paint:(CGContextRef)context opacity:(CGFloat)opacity painter:(RNSVGPainter *)painter; - (void)paint:(CGContextRef)context opacity:(CGFloat)opacity painter:(RNSVGPainter *)painter bounds:(CGRect)bounds;
@end @end
+1 -1
View File
@@ -14,7 +14,7 @@
- (instancetype)initWithPointsArray:(NSArray<NSString *> *)pointsArray NS_DESIGNATED_INITIALIZER; - (instancetype)initWithPointsArray:(NSArray<NSString *> *)pointsArray NS_DESIGNATED_INITIALIZER;
- (void)paint:(CGContextRef)context; - (void)paint:(CGContextRef)context bounds:(CGRect)bounds;
- (void)setUnits:(RNSVGUnits)unit; - (void)setUnits:(RNSVGUnits)unit;
+9 -9
View File
@@ -66,20 +66,20 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
_colors = colors; _colors = colors;
} }
- (void)paint:(CGContextRef)context - (void)paint:(CGContextRef)context bounds:(CGRect)bounds
{ {
if (_type == kRNSVGLinearGradient) { if (_type == kRNSVGLinearGradient) {
[self paintLinearGradient:context]; [self paintLinearGradient:context bounds:(CGRect)bounds];
} else if (_type == kRNSVGRadialGradient) { } else if (_type == kRNSVGRadialGradient) {
[self paintRidialGradient:context]; [self paintRidialGradient:context bounds:(CGRect)bounds];
} else if (_type == kRNSVGPattern) { } else if (_type == kRNSVGPattern) {
// todo: // todo:
} }
} }
- (CGRect)getPaintRect:(CGContextRef)context - (CGRect)getPaintRect:(CGContextRef)context bounds:(CGRect)bounds
{ {
CGRect rect = _useObjectBoundingBox ? CGContextGetClipBoundingBox(context) : _userSpaceBoundingBox; CGRect rect = _useObjectBoundingBox ? bounds : _userSpaceBoundingBox;
float height = CGRectGetHeight(rect); float height = CGRectGetHeight(rect);
float width = CGRectGetWidth(rect); float width = CGRectGetWidth(rect);
float x = 0.0; float x = 0.0;
@@ -93,13 +93,13 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
return CGRectMake(x, y, width, height); return CGRectMake(x, y, width, height);
} }
- (void)paintLinearGradient:(CGContextRef)context - (void)paintLinearGradient:(CGContextRef)context bounds:(CGRect)bounds
{ {
CGGradientRef gradient = CGGradientRetain([RCTConvert RNSVGCGGradient:_colors offset:0]); CGGradientRef gradient = CGGradientRetain([RCTConvert RNSVGCGGradient:_colors offset:0]);
CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation; CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
CGRect rect = [self getPaintRect:context]; CGRect rect = [self getPaintRect:context bounds:bounds];
float height = CGRectGetHeight(rect); float height = CGRectGetHeight(rect);
float width = CGRectGetWidth(rect); float width = CGRectGetWidth(rect);
float offsetX = CGRectGetMinX(rect); float offsetX = CGRectGetMinX(rect);
@@ -124,12 +124,12 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
CGGradientRelease(gradient); CGGradientRelease(gradient);
} }
- (void)paintRidialGradient:(CGContextRef)context - (void)paintRidialGradient:(CGContextRef)context bounds:(CGRect)bounds
{ {
CGGradientRef gradient = CGGradientRetain([RCTConvert RNSVGCGGradient:_colors offset:0]); CGGradientRef gradient = CGGradientRetain([RCTConvert RNSVGCGGradient:_colors offset:0]);
CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation; CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
CGRect rect = [self getPaintRect:context]; CGRect rect = [self getPaintRect:context bounds:bounds];
float height = CGRectGetHeight(rect); float height = CGRectGetHeight(rect);
float width = CGRectGetWidth(rect); float width = CGRectGetWidth(rect);
float offsetX = CGRectGetMinX(rect); float offsetX = CGRectGetMinX(rect);
+5 -5
View File
@@ -21,22 +21,22 @@
self.class, NSStringFromSelector(_cmd), array); self.class, NSStringFromSelector(_cmd), array);
return nil; return nil;
} }
self.brushRef = [array objectAtIndex:1]; self.brushRef = [array objectAtIndex:1];
} }
return self; return self;
} }
- (void)paint:(CGContextRef)context opacity:(CGFloat)opacity painter:(RNSVGPainter *)painter - (void)paint:(CGContextRef)context opacity:(CGFloat)opacity painter:(RNSVGPainter *)painter bounds:(CGRect)bounds
{ {
BOOL transparency = opacity < 1; BOOL transparency = opacity < 1;
if (transparency) { if (transparency) {
CGContextSetAlpha(context, opacity); CGContextSetAlpha(context, opacity);
CGContextBeginTransparencyLayer(context, NULL); CGContextBeginTransparencyLayer(context, NULL);
} }
[painter paint:context]; [painter paint:context bounds:(CGRect)bounds];
if (transparency) { if (transparency) {
CGContextEndTransparencyLayer(context); CGContextEndTransparencyLayer(context);
} }
+2
View File
@@ -211,6 +211,7 @@
[self.fill paint:context [self.fill paint:context
opacity:self.fillOpacity opacity:self.fillOpacity
painter:[self.svgView getDefinedPainter:self.fill.brushRef] painter:[self.svgView getDefinedPainter:self.fill.brushRef]
bounds:pathBounding
]; ];
CGContextRestoreGState(context); CGContextRestoreGState(context);
@@ -256,6 +257,7 @@
[self.stroke paint:context [self.stroke paint:context
opacity:self.strokeOpacity opacity:self.strokeOpacity
painter:[self.svgView getDefinedPainter:self.stroke.brushRef] painter:[self.svgView getDefinedPainter:self.stroke.brushRef]
bounds:pathBounding
]; ];
return; return;
} }