From 70c54e61a4d63cef9e7cdbfbd24c8e009c2ef559 Mon Sep 17 00:00:00 2001 From: Mikael Sand Date: Sat, 28 Sep 2019 00:45:07 +0300 Subject: [PATCH] fix: units in linear and radial gradients fixes #1110 fixes #1118 --- .../src/main/java/com/horcrux/svg/Brush.java | 23 ++++--- ios/Brushes/RNSVGBrush.h | 1 - ios/Brushes/RNSVGPainter.m | 55 ++++++--------- ios/RNSVGRenderable.h | 1 - ios/Utils/RNSVGPercentageConverter.h | 23 ------- ios/Utils/RNSVGPercentageConverter.m | 67 ------------------- src/elements/RadialGradient.tsx | 4 +- 7 files changed, 34 insertions(+), 140 deletions(-) delete mode 100644 ios/Utils/RNSVGPercentageConverter.h delete mode 100644 ios/Utils/RNSVGPercentageConverter.m diff --git a/android/src/main/java/com/horcrux/svg/Brush.java b/android/src/main/java/com/horcrux/svg/Brush.java index b428f7e75..b22d760d7 100644 --- a/android/src/main/java/com/horcrux/svg/Brush.java +++ b/android/src/main/java/com/horcrux/svg/Brush.java @@ -171,10 +171,10 @@ void setupPaint(Paint paint, RectF pathBoundingBox, float scale, float opacity) } if (mType == BrushType.LINEAR_GRADIENT) { - double x1 = PropHelper.fromRelative(mPoints[0], width, offsetX, scale, textSize); - double y1 = PropHelper.fromRelative(mPoints[1], height, offsetY, scale, textSize); - double x2 = PropHelper.fromRelative(mPoints[2], width, offsetX, scale, textSize); - double y2 = PropHelper.fromRelative(mPoints[3], height, offsetY, scale, textSize); + double x1 = getVal(mPoints[0], width, scale, textSize) + offsetX; + double y1 = getVal(mPoints[1], height, scale, textSize) + offsetY; + double x2 = getVal(mPoints[2], width, scale, textSize) + offsetX; + double y2 = getVal(mPoints[3], height, scale, textSize) + offsetY; Shader linearGradient = new LinearGradient( (float) x1, @@ -193,13 +193,18 @@ void setupPaint(Paint paint, RectF pathBoundingBox, float scale, float opacity) paint.setShader(linearGradient); } else if (mType == BrushType.RADIAL_GRADIENT) { - double rx = PropHelper.fromRelative(mPoints[2], width, 0f, scale, textSize); - double ry = PropHelper.fromRelative(mPoints[3], height, 0f, scale, textSize); - double cx = PropHelper.fromRelative(mPoints[4], width, offsetX, scale, textSize); - double cy = PropHelper.fromRelative(mPoints[5], height, offsetY, scale, textSize) / (ry / rx); + double rx = getVal(mPoints[2], width, scale, textSize); + double ry = getVal(mPoints[3], height, scale, textSize); + + double ratio = ry / rx; + + double cx = getVal(mPoints[4], width, scale, textSize) + offsetX; + double cy = getVal(mPoints[5], height, scale, textSize) + offsetY / ratio; + // TODO: support focus point. //double fx = PropHelper.fromRelative(mPoints[0], width, offsetX, scale); //double fy = PropHelper.fromRelative(mPoints[1], height, offsetY, scale) / (ry / rx); + Shader radialGradient = new RadialGradient( (float) cx, (float) cy, @@ -210,7 +215,7 @@ void setupPaint(Paint paint, RectF pathBoundingBox, float scale, float opacity) ); Matrix radialMatrix = new Matrix(); - radialMatrix.preScale(1f, (float) (ry / rx)); + radialMatrix.preScale(1f, (float) ratio); if (mMatrix != null) { radialMatrix.preConcat(mMatrix); diff --git a/ios/Brushes/RNSVGBrush.h b/ios/Brushes/RNSVGBrush.h index 874714537..ee72401fe 100644 --- a/ios/Brushes/RNSVGBrush.h +++ b/ios/Brushes/RNSVGBrush.h @@ -8,7 +8,6 @@ #import #import -#import "RNSVGPercentageConverter.h" #import "RNSVGPainter.h" @interface RNSVGBrush : NSObject diff --git a/ios/Brushes/RNSVGPainter.m b/ios/Brushes/RNSVGPainter.m index b7361681b..eb4602433 100644 --- a/ios/Brushes/RNSVGPainter.m +++ b/ios/Brushes/RNSVGPainter.m @@ -8,7 +8,6 @@ #import "RNSVGPainter.h" #import "RNSVGPattern.h" -#import "RNSVGPercentageConverter.h" #import "RNSVGViewBox.h" @implementation RNSVGPainter @@ -188,7 +187,6 @@ - (void)paintPattern:(CGContextRef)context bounds:(CGRect)bounds - (void)paintLinearGradient:(CGContextRef)context bounds:(CGRect)bounds { - CGGradientRef gradient = CGGradientRetain([RCTConvert RNSVGCGGradient:_colors]); CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation; @@ -198,19 +196,10 @@ - (void)paintLinearGradient:(CGContextRef)context bounds:(CGRect)bounds CGFloat offsetX = CGRectGetMinX(rect); CGFloat offsetY = CGRectGetMinY(rect); - CGFloat x1 = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:0] - relative:width - offset:offsetX]; - CGFloat y1 = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:1] - relative:height - offset:offsetY]; - CGFloat x2 = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:2] - relative:width - offset:offsetX]; - CGFloat y2 = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:3] - relative:height - offset:offsetY]; - + CGFloat x1 = [self getVal:[_points objectAtIndex:0] relative:width] + offsetX; + CGFloat y1 = [self getVal:[_points objectAtIndex:1] relative:height] + offsetY; + CGFloat x2 = [self getVal:[_points objectAtIndex:2] relative:width] + offsetX; + CGFloat y2 = [self getVal:[_points objectAtIndex:3] relative:height] + offsetY; CGContextConcatCTM(context, _transform); CGContextDrawLinearGradient(context, gradient, CGPointMake(x1, y1), CGPointMake(x2, y2), extendOptions); @@ -223,31 +212,25 @@ - (void)paintRadialGradient:(CGContextRef)context bounds:(CGRect)bounds CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation; CGRect rect = [self getPaintRect:context bounds:bounds]; - CGFloat height = CGRectGetHeight(rect); + CGFloat width = CGRectGetWidth(rect); + CGFloat height = CGRectGetHeight(rect); + CGFloat offsetX = CGRectGetMinX(rect); CGFloat offsetY = CGRectGetMinY(rect); - CGFloat rx = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:2] - relative:width - offset:0]; - CGFloat ry = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:3] - relative:height - offset:0]; - CGFloat fx = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:0] - relative:width - offset:offsetX]; - CGFloat fy = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:1] - relative:height - offset:offsetY] / (ry / rx); - CGFloat cx = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:4] - relative:width - offset:offsetX]; - CGFloat cy = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:5] - relative:height - offset:offsetY] / (ry / rx); - - CGAffineTransform transform = CGAffineTransformMakeScale(1, ry / rx); + CGFloat rx = [self getVal:[_points objectAtIndex:2] relative:width]; + CGFloat ry = [self getVal:[_points objectAtIndex:3] relative:height]; + + double ratio = ry / rx; + + CGFloat fx = [self getVal:[_points objectAtIndex:0] relative:width] + offsetX; + CGFloat fy = ([self getVal:[_points objectAtIndex:1] relative:height] + offsetY) / ratio; + + CGFloat cx = [self getVal:[_points objectAtIndex:4] relative:width] + offsetX; + CGFloat cy = ([self getVal:[_points objectAtIndex:5] relative:height] + offsetY) / ratio; + + CGAffineTransform transform = CGAffineTransformMakeScale(1, ratio); CGContextConcatCTM(context, transform); CGContextConcatCTM(context, _transform); diff --git a/ios/RNSVGRenderable.h b/ios/RNSVGRenderable.h index 2973f25ba..5a4dd5391 100644 --- a/ios/RNSVGRenderable.h +++ b/ios/RNSVGRenderable.h @@ -13,7 +13,6 @@ #import "RNSVGNode.h" #import "RNSVGLength.h" #import "RNSVGVectorEffect.h" -#import "RNSVGPercentageConverter.h" @interface RNSVGRenderable : RNSVGNode diff --git a/ios/Utils/RNSVGPercentageConverter.h b/ios/Utils/RNSVGPercentageConverter.h deleted file mode 100644 index 5869ae8a6..000000000 --- a/ios/Utils/RNSVGPercentageConverter.h +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright (c) 2015-present, Horcrux. - * All rights reserved. - * - * This source code is licensed under the MIT-style license found in the - * LICENSE file in the root directory of this source tree. - */ - -#import -#import -#import "RNSVGLength.h" - -@interface RNSVGPercentageConverter : NSObject - -+ (CGFloat) percentageToFloat:(NSString *)percentage relative:(CGFloat)relative offset:(CGFloat)offset; - -+ (CGFloat) stringToFloat:(NSString *)string relative:(CGFloat)relative offset:(CGFloat)offset; - -+ (BOOL) isPercentage:(NSString *) string; - -+ (CGFloat)lengthToFloat:(RNSVGLength *)length relative:(CGFloat)relative offset:(CGFloat)offset; - -@end diff --git a/ios/Utils/RNSVGPercentageConverter.m b/ios/Utils/RNSVGPercentageConverter.m deleted file mode 100644 index bfa783ff8..000000000 --- a/ios/Utils/RNSVGPercentageConverter.m +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Copyright (c) 2015-present, Horcrux. - * All rights reserved. - * - * This source code is licensed under the MIT-style license found in the - * LICENSE file in the root directory of this source tree. - */ - -#import "RNSVGPercentageConverter.h" - -@implementation RNSVGPercentageConverter - -static NSRegularExpression* percentageRegExp; - -+(void)initialize -{ - percentageRegExp = [[NSRegularExpression alloc] initWithPattern:@"^(\\-?\\d+(?:\\.\\d+)?)%$" options:0 error:nil]; -} - -+ (CGFloat)stringToFloat:(NSString *)string relative:(CGFloat)relative offset:(CGFloat)offset -{ - if (string == nil) { - return offset; - } else if (![self isPercentage:string]) { - return (CGFloat)[string doubleValue] + offset; - } else { - return [self percentageToFloat:string relative:relative offset:offset]; - } -} - -+ (CGFloat)lengthToFloat:(RNSVGLength *)length relative:(CGFloat)relative offset:(CGFloat)offset -{ - if (length == nil) { - return offset; - } else if ([length unit] != SVG_LENGTHTYPE_PERCENTAGE) { - return [length value] + offset; - } else { - return [length value] / 100 * relative + offset; - } -} - -+ (CGFloat)percentageToFloat:(NSString *)percentage relative:(CGFloat)relative offset:(CGFloat)offset -{ - __block CGFloat matched; - - [percentageRegExp enumerateMatchesInString:percentage - options:0 - range:NSMakeRange(0, percentage.length) - usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) - { - - matched = (CGFloat)[[percentage substringWithRange:NSMakeRange(result.range.location, result.range.length)] doubleValue]; - matched = matched / 100 * relative + offset; - }]; - - return matched; -} - -+ (BOOL)isPercentage:(NSString *) string -{ - if (![string isKindOfClass:[NSString class]]) { - return NO; - } - return [percentageRegExp firstMatchInString:string options:0 range:NSMakeRange(0, [string length])] != nil; -} - -@end diff --git a/src/elements/RadialGradient.tsx b/src/elements/RadialGradient.tsx index 8129665a4..4a7c74f5d 100644 --- a/src/elements/RadialGradient.tsx +++ b/src/elements/RadialGradient.tsx @@ -21,8 +21,6 @@ export default class RadialGradient extends Shape<{ static displayName = 'RadialGradient'; static defaultProps = { - fx: '50%', - fy: '50%', cx: '50%', cy: '50%', r: '50%', @@ -30,7 +28,7 @@ export default class RadialGradient extends Shape<{ render() { const { props } = this; - const { fx, fy, rx, ry, r, cx, cy } = props; + const { rx, ry, r, cx, cy, fx = cx, fy = cy } = props; return (