From a8fe15c506561d0df43774beb4017335de35de73 Mon Sep 17 00:00:00 2001 From: Mikael Sand Date: Fri, 19 Oct 2018 01:19:35 +0300 Subject: [PATCH] [iOS] Refactor remaining uses of NSString to SVGLength --- ios/Brushes/RNSVGPainter.m | 28 +++---- ios/Elements/RNSVGSvgView.m | 4 + ios/RNSVGNode.m | 52 +++++++++++- ios/RNSVGRenderable.m | 2 +- ios/Text/RNSVGGlyphContext.h | 2 +- ios/Text/RNSVGGlyphContext.m | 98 +++++++++++------------ ios/Text/RNSVGPropHelper.h | 2 - ios/Text/RNSVGPropHelper.m | 10 +-- ios/Text/RNSVGTSpan.m | 14 ++-- ios/Text/RNSVGText.h | 12 +-- ios/Text/RNSVGText.m | 16 ++-- ios/Utils/RCTConvert+RNSVG.h | 1 + ios/Utils/RCTConvert+RNSVG.m | 21 +++++ ios/Utils/RNSVGPercentageConverter.h | 3 + ios/Utils/RNSVGPercentageConverter.m | 17 +++- ios/ViewManagers/RNSVGNodeManager.m | 92 +++++++++++++++++---- ios/ViewManagers/RNSVGRenderableManager.m | 2 +- ios/ViewManagers/RNSVGTextManager.m | 70 ++-------------- 18 files changed, 262 insertions(+), 184 deletions(-) diff --git a/ios/Brushes/RNSVGPainter.m b/ios/Brushes/RNSVGPainter.m index 7ebcd5d1..5aaeb237 100644 --- a/ios/Brushes/RNSVGPainter.m +++ b/ios/Brushes/RNSVGPainter.m @@ -135,16 +135,16 @@ void PatternFunction(void* info, CGContextRef context) float offsetX = CGRectGetMinX(rect); float offsetY = CGRectGetMinY(rect); - CGFloat x = [RNSVGPercentageConverter stringToFloat:(NSString *)[_points objectAtIndex:0] + CGFloat x = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:0] relative:width offset:offsetX]; - CGFloat y = [RNSVGPercentageConverter stringToFloat:(NSString *)[_points objectAtIndex:1] + CGFloat y = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:1] relative:height offset:offsetY]; - CGFloat w = [RNSVGPercentageConverter stringToFloat:(NSString *)[_points objectAtIndex:2] + CGFloat w = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:2] relative:width offset:offsetX]; - CGFloat h = [RNSVGPercentageConverter stringToFloat:(NSString *)[_points objectAtIndex:3] + CGFloat h = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:3] relative:height offset:offsetY]; @@ -185,16 +185,16 @@ void PatternFunction(void* info, CGContextRef context) float offsetX = CGRectGetMinX(rect); float offsetY = CGRectGetMinY(rect); - CGFloat x1 = [RNSVGPercentageConverter stringToFloat:(NSString *)[_points objectAtIndex:0] + CGFloat x1 = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:0] relative:width offset:offsetX]; - CGFloat y1 = [RNSVGPercentageConverter stringToFloat:(NSString *)[_points objectAtIndex:1] + CGFloat y1 = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:1] relative:height offset:offsetY]; - CGFloat x2 = [RNSVGPercentageConverter stringToFloat:(NSString *)[_points objectAtIndex:2] + CGFloat x2 = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:2] relative:width offset:offsetX]; - CGFloat y2 = [RNSVGPercentageConverter stringToFloat:(NSString *)[_points objectAtIndex:3] + CGFloat y2 = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:3] relative:height offset:offsetY]; @@ -215,22 +215,22 @@ void PatternFunction(void* info, CGContextRef context) float offsetX = CGRectGetMinX(rect); float offsetY = CGRectGetMinY(rect); - CGFloat rx = [RNSVGPercentageConverter stringToFloat:(NSString *)[_points objectAtIndex:2] + CGFloat rx = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:2] relative:width offset:0]; - CGFloat ry = [RNSVGPercentageConverter stringToFloat:(NSString *)[_points objectAtIndex:3] + CGFloat ry = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:3] relative:height offset:0]; - CGFloat fx = [RNSVGPercentageConverter stringToFloat:(NSString *)[_points objectAtIndex:0] + CGFloat fx = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:0] relative:width offset:offsetX]; - CGFloat fy = [RNSVGPercentageConverter stringToFloat:(NSString *)[_points objectAtIndex:1] + CGFloat fy = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:1] relative:height offset:offsetY] / (ry / rx); - CGFloat cx = [RNSVGPercentageConverter stringToFloat:(NSString *)[_points objectAtIndex:4] + CGFloat cx = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:4] relative:width offset:offsetX]; - CGFloat cy = [RNSVGPercentageConverter stringToFloat:(NSString *)[_points objectAtIndex:5] + CGFloat cy = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:5] relative:height offset:offsetY] / (ry / rx); diff --git a/ios/Elements/RNSVGSvgView.m b/ios/Elements/RNSVGSvgView.m index e4aabef7..46b21fc6 100644 --- a/ios/Elements/RNSVGSvgView.m +++ b/ios/Elements/RNSVGSvgView.m @@ -184,6 +184,10 @@ - (void)drawRect:(CGRect)rect { + UIView* parent = self.superview; + if ([parent isKindOfClass:[RNSVGNode class]]) { + return; + } rendered = true; _clipPaths = nil; _templates = nil; diff --git a/ios/RNSVGNode.m b/ios/RNSVGNode.m index 25a16c67..3dd73d0b 100644 --- a/ios/RNSVGNode.m +++ b/ios/RNSVGNode.m @@ -23,6 +23,9 @@ BOOL _transparent; CGPathRef _cachedClipPath; CGImageRef _clipMask; + double canvasWidth; + double canvasHeight; + double canvasDiagonal; } CGFloat const RNSVG_M_SQRT1_2l = 0.707106781186547524400844362104849039; @@ -59,6 +62,9 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12; id container = (id)self.superview; [container invalidate]; [self clearPath]; + canvasWidth = -1; + canvasHeight = -1; + canvasDiagonal = -1; } - (void)clearPath @@ -362,7 +368,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12; if (unit == SVG_LENGTHTYPE_NUMBER){ return length.value; } else if (unit == SVG_LENGTHTYPE_PERCENTAGE){ - return length.value / 100 * [self getContextWidth]; + return length.value / 100 * [self getCanvasWidth]; } return [self fromRelative:length]; } @@ -373,7 +379,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12; if (unit == SVG_LENGTHTYPE_NUMBER){ return length.value; } else if (unit == SVG_LENGTHTYPE_PERCENTAGE){ - return length.value / 100 * [self getContextHeight]; + return length.value / 100 * [self getCanvasHeight]; } return [self fromRelative:length]; } @@ -384,7 +390,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12; if (unit == SVG_LENGTHTYPE_NUMBER){ return length.value; } else if (unit == SVG_LENGTHTYPE_PERCENTAGE){ - return length.value / 100 * [self getContextDiagonal]; + return length.value / 100 * [self getCanvasDiagonal]; } return [self fromRelative:length]; } @@ -446,6 +452,46 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12; return r; } +- (CGFloat) getCanvasWidth { + if (canvasWidth != -1) { + return canvasWidth; + } + RNSVGGroup* root = [self textRoot]; + if (root == nil) { + canvasWidth = [self getContextWidth]; + } else { + canvasWidth = [[root getGlyphContext] getWidth]; + } + + return canvasWidth; +} + +- (CGFloat) getCanvasHeight { + if (canvasHeight != -1) { + return canvasHeight; + } + RNSVGGroup* root = [self textRoot]; + if (root == nil) { + canvasHeight = [self getContextHeight]; + } else { + canvasHeight = [[root getGlyphContext] getHeight]; + } + + return canvasHeight; +} + +- (CGFloat) getCanvasDiagonal { + if (canvasDiagonal != -1) { + return canvasDiagonal; + } + CGFloat width = [self getCanvasWidth]; + CGFloat height = [self getCanvasHeight]; + CGFloat powX = width * width; + CGFloat powY = height * height; + canvasDiagonal = sqrt(powX + powY) * RNSVG_M_SQRT1_2l; + return canvasDiagonal; +} + - (void)parseReference { if (self.name) { diff --git a/ios/RNSVGRenderable.m b/ios/RNSVGRenderable.m index 8dd615f3..fa9852ad 100644 --- a/ios/RNSVGRenderable.m +++ b/ios/RNSVGRenderable.m @@ -320,7 +320,7 @@ UInt32 saturate(double value) { } if (self.stroke) { - CGFloat width = [self relativeOnOther:self.strokeWidth]; + CGFloat width = self.strokeWidth ? [self relativeOnOther:self.strokeWidth] : 1; CGContextSetLineWidth(context, width); CGContextSetLineCap(context, self.strokeLinecap); CGContextSetLineJoin(context, self.strokeLinejoin); diff --git a/ios/Text/RNSVGGlyphContext.h b/ios/Text/RNSVGGlyphContext.h index b99718c5..bcab135a 100644 --- a/ios/Text/RNSVGGlyphContext.h +++ b/ios/Text/RNSVGGlyphContext.h @@ -26,7 +26,7 @@ - (double)nextDeltaY; -- (NSNumber*)nextRotation; +- (double)nextRotation; - (double)nextXWithDouble:(double)advance; diff --git a/ios/Text/RNSVGGlyphContext.m b/ios/Text/RNSVGGlyphContext.m index cdf8d00e..4416957e 100644 --- a/ios/Text/RNSVGGlyphContext.m +++ b/ios/Text/RNSVGGlyphContext.m @@ -12,25 +12,25 @@ NSMutableArray *mFontContext_; // Unique input attribute lists (only added if node sets a value) - NSMutableArray *mXsContext_; - NSMutableArray *mYsContext_; - NSMutableArray *mDXsContext_; - NSMutableArray *mDYsContext_; - NSMutableArray *mRsContext_; + NSMutableArray*> *mXsContext_; + NSMutableArray*> *mYsContext_; + NSMutableArray*> *mDXsContext_; + NSMutableArray*> *mDYsContext_; + NSMutableArray*> *mRsContext_; // Unique index into attribute list (one per unique list) - NSMutableArray *mXIndices_; - NSMutableArray *mYIndices_; - NSMutableArray *mDXIndices_; - NSMutableArray *mDYIndices_; - NSMutableArray *mRIndices_; + NSMutableArray *mXIndices_; + NSMutableArray *mYIndices_; + NSMutableArray *mDXIndices_; + NSMutableArray *mDYIndices_; + NSMutableArray *mRIndices_; // Index of unique context used (one per node push/pop) - NSMutableArray *mXsIndices_; - NSMutableArray *mYsIndices_; - NSMutableArray *mDXsIndices_; - NSMutableArray *mDYsIndices_; - NSMutableArray *mRsIndices_; + NSMutableArray *mXsIndices_; + NSMutableArray *mYsIndices_; + NSMutableArray *mDXsIndices_; + NSMutableArray *mDYsIndices_; + NSMutableArray *mRsIndices_; // Calculated on push context, percentage and em length depends on parent font size double mFontSize_; @@ -51,25 +51,25 @@ // https://www.w3.org/TR/SVG/types.html#DataTypeCoordinates // https://www.w3.org/TR/SVG/text.html#TSpanElementXAttribute - NSArray *mXs_; + NSArray *mXs_; // https://www.w3.org/TR/SVG/text.html#TSpanElementYAttribute - NSArray *mYs_; + NSArray *mYs_; // Current SVGLengthList // https://www.w3.org/TR/SVG/types.html#DataTypeLengths // https://www.w3.org/TR/SVG/text.html#TSpanElementDXAttribute - NSArray *mDXs_; + NSArray *mDXs_; // https://www.w3.org/TR/SVG/text.html#TSpanElementDYAttribute - NSArray *mDYs_; + NSArray *mDYs_; // Current SVGLengthList // https://www.w3.org/TR/SVG/types.html#DataTypeNumbers // https://www.w3.org/TR/SVG/text.html#TSpanElementRotateAttribute - NSArray *mRs_; + NSArray *mRs_; // Current attribute list index long mXsIndex_; @@ -179,7 +179,7 @@ self->mYs_ = [[NSArray alloc]init]; self->mDXs_ = [[NSArray alloc]init]; self->mDYs_ = [[NSArray alloc]init]; - self->mRs_ = [[NSArray alloc]initWithObjects:@0, nil]; + self->mRs_ = [[NSArray alloc]initWithObjects:[RNSVGLength lengthWithNumber:0], nil]; self->mXIndex_ = -1; self->mYIndex_ = -1; @@ -254,11 +254,11 @@ - (void)pushContext:(RNSVGText*)node font:(NSDictionary*)font - x:(NSArray*)x - y:(NSArray*)y - deltaX:(NSArray*)deltaX - deltaY:(NSArray*)deltaY - rotate:(NSArray*)rotate { + x:(NSArray*)x + y:(NSArray*)y + deltaX:(NSArray*)deltaX + deltaY:(NSArray*)deltaY + rotate:(NSArray*)rotate { [self pushNode:(RNSVGGroup*)node andFont:font]; if (x != nil && [x count] != 0) { mXsIndex_++; @@ -292,7 +292,7 @@ mRsIndex_++; mRIndex_ = -1; [mRIndices_ addObject:[NSNumber numberWithLong:mRIndex_]]; - mRs_ = [rotate valueForKeyPath:@"self.doubleValue"]; + mRs_ = rotate; [mRsContext_ addObject:mRs_]; } [self pushIndices]; @@ -398,12 +398,10 @@ if (nextIndex < [mXs_ count]) { mDX_ = 0; mXIndex_ = nextIndex; - NSString *string = [mXs_ objectAtIndex:nextIndex]; - mX_ = [RNSVGPropHelper fromRelativeWithNSString:string - relative:mWidth_ - offset:0 - scale:mScale_ - fontSize:mFontSize_]; + RNSVGLength *length = [mXs_ objectAtIndex:nextIndex]; + mX_ = [RNSVGPropHelper fromRelative:length + relative:mWidth_ + fontSize:mFontSize_]; } mX_ += advance; return mX_; @@ -415,12 +413,10 @@ if (nextIndex < [mYs_ count]) { mDY_ = 0; mYIndex_ = nextIndex; - NSString *string = [mYs_ objectAtIndex:nextIndex]; - mY_ = [RNSVGPropHelper fromRelativeWithNSString:string - relative:mHeight_ - offset:0 - scale:mScale_ - fontSize:mFontSize_]; + RNSVGLength *length = [mYs_ objectAtIndex:nextIndex]; + mY_ = [RNSVGPropHelper fromRelative:length + relative:mHeight_ + fontSize:mFontSize_]; } return mY_; } @@ -430,12 +426,10 @@ long nextIndex = mDXIndex_ + 1; if (nextIndex < [mDXs_ count]) { mDXIndex_ = nextIndex; - NSString *string = [mDXs_ objectAtIndex:nextIndex]; - double val = [RNSVGPropHelper fromRelativeWithNSString:string - relative:mWidth_ - offset:0 - scale:mScale_ - fontSize:mFontSize_]; + RNSVGLength *length = [mDXs_ objectAtIndex:nextIndex]; + double val = [RNSVGPropHelper fromRelative:length + relative:mWidth_ + fontSize:mFontSize_]; mDX_ += val; } return mDX_; @@ -446,18 +440,16 @@ long nextIndex = mDYIndex_ + 1; if (nextIndex < [mDYs_ count]) { mDYIndex_ = nextIndex; - NSString *string = [mDYs_ objectAtIndex:nextIndex]; - double val = [RNSVGPropHelper fromRelativeWithNSString:string - relative:mHeight_ - offset:0 - scale:mScale_ - fontSize:mFontSize_]; + RNSVGLength *length = [mDYs_ objectAtIndex:nextIndex]; + double val = [RNSVGPropHelper fromRelative:length + relative:mHeight_ + fontSize:mFontSize_]; mDY_ += val; } return mDY_; } -- (NSNumber*)nextRotation { +- (double)nextRotation { [RNSVGGlyphContext incrementIndices:mRIndices_ topIndex:mRsIndex_]; long nextIndex = mRIndex_ + 1; long count = [mRs_ count]; @@ -466,7 +458,7 @@ } else { mRIndex_ = count - 1; } - return mRs_[mRIndex_]; + return [mRs_[mRIndex_] value]; } - (float)getWidth { diff --git a/ios/Text/RNSVGPropHelper.h b/ios/Text/RNSVGPropHelper.h index 2406655c..2da917f5 100644 --- a/ios/Text/RNSVGPropHelper.h +++ b/ios/Text/RNSVGPropHelper.h @@ -15,8 +15,6 @@ + (double) fromRelative:(RNSVGLength*)length relative:(double)relative - offset:(double)offset - scale:(double)scale fontSize:(double)fontSize; + (double)fromRelative:(RNSVGLength*)length diff --git a/ios/Text/RNSVGPropHelper.m b/ios/Text/RNSVGPropHelper.m index 9a2aba6d..5d242c5b 100644 --- a/ios/Text/RNSVGPropHelper.m +++ b/ios/Text/RNSVGPropHelper.m @@ -50,8 +50,6 @@ + (double)fromRelative:(RNSVGLength*)length relative:(double)relative - offset:(double)offset - scale:(double)scale fontSize:(double)fontSize { RNSVGLengthUnitType unitType = length.unit; double value = length.value; @@ -59,10 +57,11 @@ switch (unitType) { case SVG_LENGTHTYPE_NUMBER: case SVG_LENGTHTYPE_PX: + return value; break; case SVG_LENGTHTYPE_PERCENTAGE: - return value / 100 * relative + offset; + return value / 100 * relative; case SVG_LENGTHTYPE_EMS: unit = fontSize; @@ -89,9 +88,9 @@ default: case SVG_LENGTHTYPE_UNKNOWN: - return value * scale + offset; + return value; } - return value * unit * scale + offset; + return value * unit; } + (double)fromRelative:(RNSVGLength*)length @@ -102,6 +101,7 @@ switch (unitType) { case SVG_LENGTHTYPE_NUMBER: case SVG_LENGTHTYPE_PX: + return value; break; case SVG_LENGTHTYPE_PERCENTAGE: diff --git a/ios/Text/RNSVGTSpan.m b/ios/Text/RNSVGTSpan.m index ba87ab8c..465c1e52 100644 --- a/ios/Text/RNSVGTSpan.m +++ b/ios/Text/RNSVGTSpan.m @@ -358,8 +358,6 @@ static double RNSVGTSpan_radToDeg = 180 / M_PI; */ double absoluteStartOffset = [RNSVGPropHelper fromRelative:textPath.startOffset relative:_pathLength - offset:0 - scale:1 fontSize:fontSize]; offset += absoluteStartOffset; if (isClosed) { @@ -452,14 +450,12 @@ static double RNSVGTSpan_radToDeg = 180 / M_PI; thus, no advance adjustments are made. */ double scaleSpacingAndGlyphs = 1; - NSString *mTextLength = [self textLength]; + RNSVGLength *mTextLength = [self textLength]; enum RNSVGTextLengthAdjust mLengthAdjust = RNSVGTextLengthAdjustFromString([self lengthAdjust]); if (mTextLength != nil) { - double author = [RNSVGPropHelper fromRelativeWithNSString:mTextLength - relative:[gc getWidth] - offset:0 - scale:1 - fontSize:fontSize]; + double author = [RNSVGPropHelper fromRelative:mTextLength + relative:[gc getWidth] + fontSize:fontSize]; if (author < 0) { NSException *e = [NSException exceptionWithName:@"NegativeTextLength" @@ -727,7 +723,7 @@ static double RNSVGTSpan_radToDeg = 180 / M_PI; double y = [gc nextY]; double dx = [gc nextDeltaX]; double dy = [gc nextDeltaY]; - double r = [[gc nextRotation] doubleValue] / RNSVGTSpan_radToDeg; + double r = [gc nextRotation] / RNSVGTSpan_radToDeg; if (isWordSeparator) { continue; diff --git a/ios/Text/RNSVGText.h b/ios/Text/RNSVGText.h index 43b98592..138f18f9 100644 --- a/ios/Text/RNSVGText.h +++ b/ios/Text/RNSVGText.h @@ -11,15 +11,15 @@ @interface RNSVGText : RNSVGGroup -@property (nonatomic, strong) NSString *textLength; +@property (nonatomic, strong) RNSVGLength *textLength; @property (nonatomic, strong) NSString *baselineShift; @property (nonatomic, strong) NSString *lengthAdjust; @property (nonatomic, strong) NSString *alignmentBaseline; -@property (nonatomic, strong) NSArray *deltaX; -@property (nonatomic, strong) NSArray *deltaY; -@property (nonatomic, strong) NSArray *positionX; -@property (nonatomic, strong) NSArray *positionY; -@property (nonatomic, strong) NSArray *rotate; +@property (nonatomic, strong) NSArray *deltaX; +@property (nonatomic, strong) NSArray *deltaY; +@property (nonatomic, strong) NSArray *positionX; +@property (nonatomic, strong) NSArray *positionY; +@property (nonatomic, strong) NSArray *rotate; - (CGPathRef)getGroupPath:(CGContextRef)context; - (CTFontRef)getFontFromContext; diff --git a/ios/Text/RNSVGText.m b/ios/Text/RNSVGText.m index b8c40c71..721dcc62 100644 --- a/ios/Text/RNSVGText.m +++ b/ios/Text/RNSVGText.m @@ -23,12 +23,12 @@ - (void)invalidate { [super invalidate]; - [self releaseCachedPath]; + //[self releaseCachedPath]; } -- (void)setTextLength:(NSString *)textLength +- (void)setTextLength:(RNSVGLength *)textLength { - if ([textLength isEqualToString:_textLength]) { + if ([textLength isEqualTo:_textLength]) { return; } [self invalidate]; @@ -62,7 +62,7 @@ _alignmentBaseline = alignmentBaseline; } -- (void)setDeltaX:(NSArray *)deltaX +- (void)setDeltaX:(NSArray *)deltaX { if (deltaX == _deltaX) { return; @@ -71,7 +71,7 @@ _deltaX = deltaX; } -- (void)setDeltaY:(NSArray *)deltaY +- (void)setDeltaY:(NSArray *)deltaY { if (deltaY == _deltaY) { return; @@ -80,7 +80,7 @@ _deltaY = deltaY; } -- (void)setPositionX:(NSArray*)positionX +- (void)setPositionX:(NSArray*)positionX { if (positionX == _positionX) { return; @@ -89,7 +89,7 @@ _positionX = positionX; } -- (void)setPositionY:(NSArray*)positionY +- (void)setPositionY:(NSArray*)positionY { if (positionY == _positionY) { return; @@ -98,7 +98,7 @@ _positionY = positionY; } -- (void)setRotate:(NSArray *)rotate +- (void)setRotate:(NSArray *)rotate { if (rotate == _rotate) { return; diff --git a/ios/Utils/RCTConvert+RNSVG.h b/ios/Utils/RCTConvert+RNSVG.h index b8d31426..c225ef00 100644 --- a/ios/Utils/RCTConvert+RNSVG.h +++ b/ios/Utils/RCTConvert+RNSVG.h @@ -22,6 +22,7 @@ @interface RCTConvert (RNSVG) + (RNSVGLength*)RNSVGLength:(id)json; ++ (NSArray*)RNSVGLengthArray:(id)json; + (RNSVGCGFCRule)RNSVGCGFCRule:(id)json; + (RNSVGVBMOS)RNSVGVBMOS:(id)json; + (RNSVGUnits)RNSVGUnits:(id)json; diff --git a/ios/Utils/RCTConvert+RNSVG.m b/ios/Utils/RCTConvert+RNSVG.m index c5da8ea6..a6b9cfd6 100644 --- a/ios/Utils/RCTConvert+RNSVG.m +++ b/ios/Utils/RCTConvert+RNSVG.m @@ -109,6 +109,27 @@ RCT_ENUM_CONVERTER(RNSVGUnits, (@{ } } ++ (NSArray*)RNSVGLengthArray:(id)json +{ + if ([json isKindOfClass:[NSNumber class]]) { + RNSVGLength* length = [RNSVGLength lengthWithNumber:[json doubleValue]]; + return [NSArray arrayWithObject:length]; + } else if ([json isKindOfClass:[NSArray class]]) { + NSArray *arrayValue = (NSArray*)json; + NSMutableArray* lengths = [NSMutableArray arrayWithCapacity:[arrayValue count]]; + for (id obj in arrayValue) { + [lengths addObject:[self RNSVGLength:obj]]; + } + return lengths; + } else if ([json isKindOfClass:[NSString class]]) { + NSString *stringValue = (NSString *)json; + RNSVGLength* length = [RNSVGLength lengthWithString:stringValue]; + return [NSArray arrayWithObject:length]; + } else { + return nil; + } +} + + (CGRect)RNSVGCGRect:(id)json offset:(NSUInteger)offset { NSArray *arr = [self NSArray:json]; diff --git a/ios/Utils/RNSVGPercentageConverter.h b/ios/Utils/RNSVGPercentageConverter.h index 24ab0556..5869ae8a 100644 --- a/ios/Utils/RNSVGPercentageConverter.h +++ b/ios/Utils/RNSVGPercentageConverter.h @@ -8,6 +8,7 @@ #import #import +#import "RNSVGLength.h" @interface RNSVGPercentageConverter : NSObject @@ -17,4 +18,6 @@ + (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 index 5d3e5815..81505c29 100644 --- a/ios/Utils/RNSVGPercentageConverter.m +++ b/ios/Utils/RNSVGPercentageConverter.m @@ -28,20 +28,31 @@ static NSRegularExpression* percentageRegExp; } } ++ (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 = [[percentage substringWithRange:NSMakeRange(result.range.location, result.range.length)] floatValue]; matched = matched / 100 * relative + offset; }]; - + return matched; } diff --git a/ios/ViewManagers/RNSVGNodeManager.m b/ios/ViewManagers/RNSVGNodeManager.m index fde71717..0a405257 100644 --- a/ios/ViewManagers/RNSVGNodeManager.m +++ b/ios/ViewManagers/RNSVGNodeManager.m @@ -64,9 +64,9 @@ static const NSUInteger kMatrixArrayLength = 4 * 4; RCTLogWarn(@"[RCTConvert CATransform3D:] has deprecated a matrix as input. Pass an array of configs (which can contain a matrix key) instead."); return [self CATransform3DFromMatrix:json]; } - + CGFloat zeroScaleThreshold = FLT_EPSILON; - + for (NSDictionary *transformConfig in (NSArray *)json) { if (transformConfig.count != 1) { RCTLogConvertError(json, @"a CATransform3D. You must specify exactly one property per transform object."); @@ -74,63 +74,63 @@ static const NSUInteger kMatrixArrayLength = 4 * 4; } NSString *property = transformConfig.allKeys[0]; id value = transformConfig[property]; - + if ([property isEqualToString:@"matrix"]) { transform = [self CATransform3DFromMatrix:value]; - + } else if ([property isEqualToString:@"perspective"]) { transform.m34 = -1 / [value floatValue]; - + } else if ([property isEqualToString:@"rotateX"]) { CGFloat rotate = [self convertToRadians:value]; transform = CATransform3DRotate(transform, rotate, 1, 0, 0); - + } else if ([property isEqualToString:@"rotateY"]) { CGFloat rotate = [self convertToRadians:value]; transform = CATransform3DRotate(transform, rotate, 0, 1, 0); - + } else if ([property isEqualToString:@"rotate"] || [property isEqualToString:@"rotateZ"]) { CGFloat rotate = [self convertToRadians:value]; transform = CATransform3DRotate(transform, rotate, 0, 0, 1); - + } else if ([property isEqualToString:@"scale"]) { CGFloat scale = [value floatValue]; scale = ABS(scale) < zeroScaleThreshold ? zeroScaleThreshold : scale; transform = CATransform3DScale(transform, scale, scale, 1); - + } else if ([property isEqualToString:@"scaleX"]) { CGFloat scale = [value floatValue]; scale = ABS(scale) < zeroScaleThreshold ? zeroScaleThreshold : scale; transform = CATransform3DScale(transform, scale, 1, 1); - + } else if ([property isEqualToString:@"scaleY"]) { CGFloat scale = [value floatValue]; scale = ABS(scale) < zeroScaleThreshold ? zeroScaleThreshold : scale; transform = CATransform3DScale(transform, 1, scale, 1); - + } else if ([property isEqualToString:@"translate"]) { NSArray *array = (NSArray *)value; CGFloat translateX = [array[0] floatValue]; CGFloat translateY = [array[1] floatValue]; CGFloat translateZ = array.count > 2 ? [array[2] floatValue] : 0; transform = CATransform3DTranslate(transform, translateX, translateY, translateZ); - + } else if ([property isEqualToString:@"translateX"]) { CGFloat translate = [value floatValue]; transform = CATransform3DTranslate(transform, translate, 0, 0); - + } else if ([property isEqualToString:@"translateY"]) { CGFloat translate = [value floatValue]; transform = CATransform3DTranslate(transform, 0, translate, 0); - + } else if ([property isEqualToString:@"skewX"]) { CGFloat skew = [self convertToRadians:value]; transform.m21 = tanf(skew); - + } else if ([property isEqualToString:@"skewY"]) { CGFloat skew = [self convertToRadians:value]; transform.m12 = tanf(skew); - + } else { RCTLogError(@"Unsupported transform type for a CATransform3D: %@.", property); } @@ -166,5 +166,65 @@ RCT_EXPORT_VIEW_PROPERTY(clipRule, RNSVGCGFCRule) RCT_EXPORT_VIEW_PROPERTY(responsible, BOOL) RCT_EXPORT_VIEW_PROPERTY(onLayout, RCTDirectEventBlock) +RCT_CUSTOM_SHADOW_PROPERTY(top, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(right, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(start, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(end, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(bottom, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(left, id, RNSVGNode) {} + +RCT_CUSTOM_SHADOW_PROPERTY(width, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(height, id, RNSVGNode) {} + +RCT_CUSTOM_SHADOW_PROPERTY(minWidth, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(maxWidth, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(minHeight, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(maxHeight, id, RNSVGNode) {} + +RCT_CUSTOM_SHADOW_PROPERTY(borderTopWidth, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(borderRightWidth, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(borderBottomWidth, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(borderLeftWidth, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(borderStartWidth, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(borderEndWidth, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(borderWidth, id, RNSVGNode) {} + +RCT_CUSTOM_SHADOW_PROPERTY(marginTop, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(marginRight, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(marginBottom, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(marginLeft, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(marginStart, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(marginEnd, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(marginVertical, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(marginHorizontal, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(margin, id, RNSVGNode) {} + +RCT_CUSTOM_SHADOW_PROPERTY(paddingTop, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(paddingRight, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(paddingBottom, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(paddingLeft, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(paddingStart, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(paddingEnd, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(paddingVertical, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(paddingHorizontal, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(padding, id, RNSVGNode) {} + +RCT_CUSTOM_SHADOW_PROPERTY(flex, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(flexGrow, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(flexShrink, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(flexBasis, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(flexDirection, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(flexWrap, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(justifyContent, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(alignItems, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(alignSelf, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(alignContent, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(position, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(aspectRatio, id, RNSVGNode) {} + +RCT_CUSTOM_SHADOW_PROPERTY(overflow, id, RNSVGNode) {} +RCT_CUSTOM_SHADOW_PROPERTY(display, id, RNSVGNode) {} + +RCT_CUSTOM_SHADOW_PROPERTY(direction, id, RNSVGNode) {} @end diff --git a/ios/ViewManagers/RNSVGRenderableManager.m b/ios/ViewManagers/RNSVGRenderableManager.m index ee978fd3..befdd937 100644 --- a/ios/ViewManagers/RNSVGRenderableManager.m +++ b/ios/ViewManagers/RNSVGRenderableManager.m @@ -28,7 +28,7 @@ RCT_EXPORT_VIEW_PROPERTY(strokeOpacity, CGFloat) RCT_EXPORT_VIEW_PROPERTY(strokeWidth, RNSVGLength*) RCT_EXPORT_VIEW_PROPERTY(strokeLinecap, CGLineCap) RCT_EXPORT_VIEW_PROPERTY(strokeLinejoin, CGLineJoin) -RCT_EXPORT_VIEW_PROPERTY(strokeDasharray, NSArray) +RCT_EXPORT_VIEW_PROPERTY(strokeDasharray, NSArray) RCT_EXPORT_VIEW_PROPERTY(strokeDashoffset, CGFloat) RCT_EXPORT_VIEW_PROPERTY(strokeMiterlimit, CGFloat) RCT_EXPORT_VIEW_PROPERTY(propList, NSArray) diff --git a/ios/ViewManagers/RNSVGTextManager.m b/ios/ViewManagers/RNSVGTextManager.m index 38475b69..cfb6e8c3 100644 --- a/ios/ViewManagers/RNSVGTextManager.m +++ b/ios/ViewManagers/RNSVGTextManager.m @@ -23,92 +23,38 @@ RCT_EXPORT_MODULE() RCT_EXPORT_VIEW_PROPERTY(textAnchor, RNSVGTextAnchor) RCT_CUSTOM_VIEW_PROPERTY(dx, id, RNSVGText) { - if ([json isKindOfClass:[NSArray class]]) { - NSArray *arrayValue = (NSArray *)json; - view.deltaX = arrayValue; - } else if ([json isKindOfClass:[NSString class]]) { - view.deltaX = [NSArray arrayWithObject:json]; - } else if ([json isKindOfClass:[NSNumber class]]) { - view.deltaX = [NSArray arrayWithObject:[NSString stringWithFormat:@"%f", [json floatValue]]]; - } + view.deltaX = [RCTConvert RNSVGLengthArray:json]; } RCT_CUSTOM_VIEW_PROPERTY(dy, id, RNSVGText) { - if ([json isKindOfClass:[NSArray class]]) { - NSArray *arrayValue = (NSArray *)json; - view.deltaY = arrayValue; - } else if ([json isKindOfClass:[NSString class]]) { - view.deltaY = [NSArray arrayWithObject:json]; - } else if ([json isKindOfClass:[NSNumber class]]) { - view.deltaY = [NSArray arrayWithObject:[NSString stringWithFormat:@"%f", [json floatValue]]]; - } + view.deltaY = [RCTConvert RNSVGLengthArray:json]; } RCT_CUSTOM_VIEW_PROPERTY(positionX, id, RNSVGText) { - if ([json isKindOfClass:[NSArray class]]) { - NSArray *arrayValue = (NSArray *)json; - view.positionX = arrayValue; - } else if ([json isKindOfClass:[NSString class]]) { - view.positionX = [NSArray arrayWithObject:json]; - } else if ([json isKindOfClass:[NSNumber class]]) { - view.positionX = [NSArray arrayWithObject:[NSString stringWithFormat:@"%f", [json floatValue]]]; - } + view.positionX = [RCTConvert RNSVGLengthArray:json]; } RCT_CUSTOM_VIEW_PROPERTY(positionY, id, RNSVGText) { - if ([json isKindOfClass:[NSArray class]]) { - NSArray *arrayValue = (NSArray *)json; - view.positionY = arrayValue; - } else if ([json isKindOfClass:[NSString class]]) { - view.positionY = [NSArray arrayWithObject:json]; - } else if ([json isKindOfClass:[NSNumber class]]) { - view.positionY = [NSArray arrayWithObject:[NSString stringWithFormat:@"%f", [json floatValue]]]; - } + view.positionY = [RCTConvert RNSVGLengthArray:json]; } RCT_CUSTOM_VIEW_PROPERTY(x, id, RNSVGText) { - if ([json isKindOfClass:[NSArray class]]) { - NSArray *arrayValue = (NSArray *)json; - view.positionX = arrayValue; - } else if ([json isKindOfClass:[NSString class]]) { - view.positionX = [NSArray arrayWithObject:json]; - } else if ([json isKindOfClass:[NSNumber class]]) { - view.positionX = [NSArray arrayWithObject:[NSString stringWithFormat:@"%f", [json floatValue]]]; - } + view.positionX = [RCTConvert RNSVGLengthArray:json]; } RCT_CUSTOM_VIEW_PROPERTY(y, id, RNSVGText) { - if ([json isKindOfClass:[NSArray class]]) { - NSArray *arrayValue = (NSArray *)json; - view.positionY = arrayValue; - } else if ([json isKindOfClass:[NSString class]]) { - view.positionY = [NSArray arrayWithObject:json]; - } else if ([json isKindOfClass:[NSNumber class]]) { - view.positionY = [NSArray arrayWithObject:[NSString stringWithFormat:@"%f", [json floatValue]]]; - } + view.positionY = [RCTConvert RNSVGLengthArray:json]; } RCT_CUSTOM_VIEW_PROPERTY(rotate, id, RNSVGText) { - if ([json isKindOfClass:[NSArray class]]) { - NSArray *arrayValue = (NSArray *)json; - view.rotate = arrayValue; - } else if ([json isKindOfClass:[NSString class]]) { - view.rotate = [NSArray arrayWithObject:json]; - } else if ([json isKindOfClass:[NSNumber class]]) { - view.rotate = [NSArray arrayWithObject:[NSString stringWithFormat:@"%f", [json floatValue]]]; - } + view.rotate = [RCTConvert RNSVGLengthArray:json]; } RCT_EXPORT_VIEW_PROPERTY(font, NSDictionary) RCT_CUSTOM_VIEW_PROPERTY(textLength, id, RNSVGText) { - if ([json isKindOfClass:[NSString class]]) { - NSString *stringValue = (NSString *)json; - view.textLength = stringValue; - } else { - view.textLength = [NSString stringWithFormat:@"%f", [json floatValue]]; - } + view.textLength = [RCTConvert RNSVGLength:json]; } RCT_CUSTOM_VIEW_PROPERTY(baselineShift, id, RNSVGText) {