From 9fe9e2d5b31d5ab9b85b6afc4a8ff0b228223ace Mon Sep 17 00:00:00 2001 From: Mikael Sand Date: Sat, 20 Oct 2018 20:46:04 +0300 Subject: [PATCH] [ios] Handle failed realloc gracefully. Change float/double to CGFloat. Reduces potential for wrong type of float given to core graphics. Reduces cpu & memory consumption on devices where CGFloat is float. Remove redundant parameters. --- ios/Brushes/RNSVGPainter.m | 36 ++++++------- ios/Elements/RNSVGGroup.m | 4 +- ios/RNSVG.xcodeproj/project.pbxproj | 2 - ios/RNSVGNode.h | 2 + ios/RNSVGNode.m | 39 +++++++------- ios/RNSVGRenderable.h | 1 - ios/RNSVGRenderable.m | 51 ++++++++++-------- ios/Text/RNSVGFontData.h | 16 +++--- ios/Text/RNSVGFontData.m | 40 +++++++------- ios/Text/RNSVGGlyphContext.h | 21 ++++---- ios/Text/RNSVGGlyphContext.m | 44 +++++++-------- ios/Text/RNSVGPropHelper.h | 18 +++---- ios/Text/RNSVGPropHelper.m | 36 ++++++------- ios/Text/RNSVGTSpan.m | 80 ++++++++++++++-------------- ios/Text/RNSVGText.m | 6 +-- ios/Utils/RCTConvert+RNSVG.h | 2 - ios/Utils/RCTConvert+RNSVG.m | 22 ++++---- ios/Utils/RNSVGCGFloatArray.h | 19 ------- ios/Utils/RNSVGLength.h | 6 ++- ios/Utils/RNSVGLength.m | 2 +- ios/Utils/RNSVGPercentageConverter.m | 4 +- ios/ViewManagers/RNSVGTextManager.m | 2 +- 22 files changed, 212 insertions(+), 241 deletions(-) delete mode 100644 ios/Utils/RNSVGCGFloatArray.h diff --git a/ios/Brushes/RNSVGPainter.m b/ios/Brushes/RNSVGPainter.m index 5aaeb237..bccc5244 100644 --- a/ios/Brushes/RNSVGPainter.m +++ b/ios/Brushes/RNSVGPainter.m @@ -90,7 +90,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) if (_type == kRNSVGLinearGradient) { [self paintLinearGradient:context bounds:(CGRect)bounds]; } else if (_type == kRNSVGRadialGradient) { - [self paintRidialGradient:context bounds:(CGRect)bounds]; + [self paintRadialGradient:context bounds:(CGRect)bounds]; } else if (_type == kRNSVGPattern) { [self paintPattern:context bounds:(CGRect)bounds]; } @@ -99,10 +99,10 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init) - (CGRect)getPaintRect:(CGContextRef)context bounds:(CGRect)bounds { CGRect rect = _useObjectBoundingBox ? bounds : _userSpaceBoundingBox; - float height = CGRectGetHeight(rect); - float width = CGRectGetWidth(rect); - float x = 0.0; - float y = 0.0; + CGFloat height = CGRectGetHeight(rect); + CGFloat width = CGRectGetWidth(rect); + CGFloat x = 0.0; + CGFloat y = 0.0; if (_useObjectBoundingBox) { x = CGRectGetMinX(rect); @@ -130,10 +130,10 @@ void PatternFunction(void* info, CGContextRef context) - (void)paintPattern:(CGContextRef)context bounds:(CGRect)bounds { CGRect rect = [self getPaintRect:context bounds:bounds]; - float height = CGRectGetHeight(rect); - float width = CGRectGetWidth(rect); - float offsetX = CGRectGetMinX(rect); - float offsetY = CGRectGetMinY(rect); + CGFloat height = CGRectGetHeight(rect); + CGFloat width = CGRectGetWidth(rect); + CGFloat offsetX = CGRectGetMinX(rect); + CGFloat offsetY = CGRectGetMinY(rect); CGFloat x = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:0] relative:width @@ -180,10 +180,10 @@ void PatternFunction(void* info, CGContextRef context) CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation; CGRect rect = [self getPaintRect:context bounds:bounds]; - float height = CGRectGetHeight(rect); - float width = CGRectGetWidth(rect); - float offsetX = CGRectGetMinX(rect); - float offsetY = CGRectGetMinY(rect); + CGFloat height = CGRectGetHeight(rect); + CGFloat width = CGRectGetWidth(rect); + CGFloat offsetX = CGRectGetMinX(rect); + CGFloat offsetY = CGRectGetMinY(rect); CGFloat x1 = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:0] relative:width @@ -204,16 +204,16 @@ void PatternFunction(void* info, CGContextRef context) CGGradientRelease(gradient); } -- (void)paintRidialGradient:(CGContextRef)context bounds:(CGRect)bounds +- (void)paintRadialGradient:(CGContextRef)context bounds:(CGRect)bounds { CGGradientRef gradient = CGGradientRetain([RCTConvert RNSVGCGGradient:_colors offset:0]); CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation; CGRect rect = [self getPaintRect:context bounds:bounds]; - float height = CGRectGetHeight(rect); - float width = CGRectGetWidth(rect); - float offsetX = CGRectGetMinX(rect); - float offsetY = CGRectGetMinY(rect); + CGFloat height = CGRectGetHeight(rect); + CGFloat width = CGRectGetWidth(rect); + CGFloat offsetX = CGRectGetMinX(rect); + CGFloat offsetY = CGRectGetMinY(rect); CGFloat rx = [RNSVGPercentageConverter lengthToFloat:[_points objectAtIndex:2] relative:width diff --git a/ios/Elements/RNSVGGroup.m b/ios/Elements/RNSVGGroup.m index 53ca7f03..b46285e7 100644 --- a/ios/Elements/RNSVGGroup.m +++ b/ios/Elements/RNSVGGroup.m @@ -86,8 +86,8 @@ CGFloat width = CGRectGetWidth(clipBounds); CGFloat height = CGRectGetHeight(clipBounds); - _glyphContext = [[RNSVGGlyphContext alloc] initWithScale:1 width:width - height:height]; + _glyphContext = [[RNSVGGlyphContext alloc] initWithWidth:width + height:height]; } - (RNSVGGlyphContext *)getGlyphContext diff --git a/ios/RNSVG.xcodeproj/project.pbxproj b/ios/RNSVG.xcodeproj/project.pbxproj index f957c92a..9e6cb6e0 100644 --- a/ios/RNSVG.xcodeproj/project.pbxproj +++ b/ios/RNSVG.xcodeproj/project.pbxproj @@ -176,7 +176,6 @@ 1039D2901CE71EC2001E90A8 /* RNSVGText.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGText.m; path = Text/RNSVGText.m; sourceTree = ""; }; 1039D29B1CE72177001E90A8 /* RCTConvert+RNSVG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "RCTConvert+RNSVG.h"; path = "Utils/RCTConvert+RNSVG.h"; sourceTree = ""; }; 1039D29C1CE72177001E90A8 /* RCTConvert+RNSVG.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "RCTConvert+RNSVG.m"; path = "Utils/RCTConvert+RNSVG.m"; sourceTree = ""; }; - 1039D29E1CE72177001E90A8 /* RNSVGCGFloatArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGCGFloatArray.h; path = Utils/RNSVGCGFloatArray.h; sourceTree = ""; }; 1039D2A11CE721A7001E90A8 /* RNSVGContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGContainer.h; sourceTree = ""; }; 1039D2AE1CE72F27001E90A8 /* RNSVGPercentageConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGPercentageConverter.h; path = Utils/RNSVGPercentageConverter.h; sourceTree = ""; }; 1039D2AF1CE72F27001E90A8 /* RNSVGPercentageConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGPercentageConverter.m; path = Utils/RNSVGPercentageConverter.m; sourceTree = ""; }; @@ -471,7 +470,6 @@ 10ABC7371D439779006CCF6E /* RNSVGCGFCRule.h */, 7FC260CC1E3499BC00A39833 /* RNSVGViewBox.h */, 7FC260CD1E3499BC00A39833 /* RNSVGViewBox.m */, - 1039D29E1CE72177001E90A8 /* RNSVGCGFloatArray.h */, 1039D2AE1CE72F27001E90A8 /* RNSVGPercentageConverter.h */, 1039D2AF1CE72F27001E90A8 /* RNSVGPercentageConverter.m */, 7F9CDAF81E1F809C00E0C805 /* RNSVGPathParser.h */, diff --git a/ios/RNSVGNode.h b/ios/RNSVGNode.h index ef6915d7..ab01511c 100644 --- a/ios/RNSVGNode.h +++ b/ios/RNSVGNode.h @@ -85,6 +85,8 @@ extern CGFloat const RNSVG_DEFAULT_FONT_SIZE; - (CGFloat)relativeOnOtherString:(NSString *)length; +- (CGFloat)relativeOn:(RNSVGLength *)length relative:(CGFloat)relative; + - (CGFloat)relativeOnWidth:(RNSVGLength *)length; - (CGFloat)relativeOnHeight:(RNSVGLength *)length; diff --git a/ios/RNSVGNode.m b/ios/RNSVGNode.m index 3dd73d0b..cfb615ee 100644 --- a/ios/RNSVGNode.m +++ b/ios/RNSVGNode.m @@ -23,9 +23,9 @@ BOOL _transparent; CGPathRef _cachedClipPath; CGImageRef _clipMask; - double canvasWidth; - double canvasHeight; - double canvasDiagonal; + CGFloat canvasWidth; + CGFloat canvasHeight; + CGFloat canvasDiagonal; } CGFloat const RNSVG_M_SQRT1_2l = 0.707106781186547524400844362104849039; @@ -332,36 +332,35 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12; - (CGFloat)relativeOnWidthString:(NSString *)length { return [RNSVGPropHelper fromRelativeWithNSString:length - relative:[self getContextWidth] - offset:0 - scale:1 + relative:[self getCanvasWidth] fontSize:[self getFontSizeFromContext]]; } - (CGFloat)relativeOnHeightString:(NSString *)length { return [RNSVGPropHelper fromRelativeWithNSString:length - relative:[self getContextHeight] - offset:0 - scale:1 + relative:[self getCanvasHeight] fontSize:[self getFontSizeFromContext]]; } - (CGFloat)relativeOnOtherString:(NSString *)length { - CGRect bounds = [self getContextBounds]; - CGFloat width = CGRectGetWidth(bounds); - CGFloat height = CGRectGetHeight(bounds); - CGFloat powX = width * width; - CGFloat powY = height * height; - CGFloat r = sqrt(powX + powY) * RNSVG_M_SQRT1_2l; return [RNSVGPropHelper fromRelativeWithNSString:length - relative:r - offset:0 - scale:1 + relative:[self getCanvasDiagonal] fontSize:[self getFontSizeFromContext]]; } +- (CGFloat)relativeOn:(RNSVGLength *)length relative:(CGFloat)relative +{ + RNSVGLengthUnitType unit = length.unit; + if (unit == SVG_LENGTHTYPE_NUMBER){ + return length.value; + } else if (unit == SVG_LENGTHTYPE_PERCENTAGE){ + return length.value / 100 * relative; + } + return [self fromRelative:length]; +} + - (CGFloat)relativeOnWidth:(RNSVGLength *)length { RNSVGLengthUnitType unit = length.unit; @@ -395,8 +394,8 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12; return [self fromRelative:length]; } -- (double)fromRelative:(RNSVGLength*)length { - double unit; +- (CGFloat)fromRelative:(RNSVGLength*)length { + CGFloat unit; switch (length.unit) { case SVG_LENGTHTYPE_EMS: unit = [self getFontSizeFromContext]; diff --git a/ios/RNSVGRenderable.h b/ios/RNSVGRenderable.h index cbcccb27..d59d48ad 100644 --- a/ios/RNSVGRenderable.h +++ b/ios/RNSVGRenderable.h @@ -9,7 +9,6 @@ #import #import "RNSVGBrush.h" -#import "RNSVGCGFloatArray.h" #import "RNSVGCGFCRule.h" #import "RNSVGNode.h" #import "RNSVGLength.h" diff --git a/ios/RNSVGRenderable.m b/ios/RNSVGRenderable.m index 904a8a63..7e137cde 100644 --- a/ios/RNSVGRenderable.m +++ b/ios/RNSVGRenderable.m @@ -161,7 +161,7 @@ } -UInt32 saturate(double value) { +UInt32 saturate(CGFloat value) { return value <= 0 ? 0 : value >= 255 ? 255 : value; } @@ -181,8 +181,8 @@ UInt32 saturate(double value) { RNSVGMask *_maskNode = (RNSVGMask*)[self.svgView getDefinedMask:self.mask]; CGRect bounds = CGContextGetClipBoundingBox(context); CGSize boundsSize = bounds.size; - float height = boundsSize.height; - float width = boundsSize.width; + CGFloat height = boundsSize.height; + CGFloat width = boundsSize.width; NSUInteger iheight = height; NSUInteger iwidth = width; NSUInteger npixels = iheight * iwidth; @@ -197,14 +197,14 @@ UInt32 saturate(double value) { CGContextRef bcontext = CGBitmapContextCreate(pixels, iwidth, iheight, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); // Clip to mask bounds and render the mask - double x = [RNSVGPropHelper fromRelative:[_maskNode x] - relative:width]; - double y = [RNSVGPropHelper fromRelative:[_maskNode y] - relative:height]; - double w = [RNSVGPropHelper fromRelative:[_maskNode maskwidth] - relative:width]; - double h = [RNSVGPropHelper fromRelative:[_maskNode maskheight] - relative:height]; + CGFloat x = [self relativeOn:[_maskNode x] + relative:width]; + CGFloat y = [self relativeOn:[_maskNode y] + relative:height]; + CGFloat w = [self relativeOn:[_maskNode maskwidth] + relative:width]; + CGFloat h = [self relativeOn:[_maskNode maskheight] + relative:height]; CGRect maskBounds = CGRectMake(x, y, w, h); CGContextClipToRect(bcontext, maskBounds); [_maskNode renderLayerTo:bcontext rect:rect]; @@ -219,7 +219,7 @@ UInt32 saturate(double value) { UInt32 g = (color >> 8) & 0xFF; UInt32 b = (color >> 16) & 0xFF; - double luma = 0.299 * r + 0.587 * g + 0.144 * b; + CGFloat luma = 0.299 * r + 0.587 * g + 0.144 * b; *currentPixel = saturate(luma) << 24; currentPixel++; } @@ -267,6 +267,20 @@ UInt32 saturate(double value) { CGContextRestoreGState(context); } +- (void)prepareStrokeDash:(NSUInteger)count strokeDasharray:(NSArray *)strokeDasharray { + if (strokeDasharray != _sourceStrokeDashArray) { + CGFloat *dash = _strokeDashArrayData; + _strokeDashArrayData = realloc(dash, sizeof(CGFloat) * count); + if (!_strokeDashArrayData) { + free(dash); + return; + } + _sourceStrokeDashArray = strokeDasharray; + for (NSUInteger i = 0; i < count; i++) { + _strokeDashArrayData[i] = (CGFloat)[self relativeOnOther:strokeDasharray[i]]; + } + } +} - (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect { @@ -330,17 +344,10 @@ UInt32 saturate(double value) { NSUInteger count = strokeDasharray.count; if (count) { - if (strokeDasharray != _sourceStrokeDashArray) { - _sourceStrokeDashArray = strokeDasharray; - if (_strokeDashArrayData) { - free(_strokeDashArrayData); - } - _strokeDashArrayData = malloc(sizeof(CGFloat) * count); - for (NSUInteger i = 0; i < count; i++) { - _strokeDashArrayData[i] = (CGFloat)[self relativeOnOther:strokeDasharray[i]]; - } + [self prepareStrokeDash:count strokeDasharray:strokeDasharray]; + if (_strokeDashArrayData) { + CGContextSetLineDash(context, self.strokeDashoffset, _strokeDashArrayData, count); } - CGContextSetLineDash(context, self.strokeDashoffset, _strokeDashArrayData, count); } if (!fillColor) { diff --git a/ios/Text/RNSVGFontData.h b/ios/Text/RNSVGFontData.h index 67be3217..22d68211 100644 --- a/ios/Text/RNSVGFontData.h +++ b/ios/Text/RNSVGFontData.h @@ -6,7 +6,7 @@ @interface RNSVGFontData : NSObject { @public - double fontSize; + CGFloat fontSize; NSString * fontSize_; NSString *fontFamily; enum RNSVGFontStyle fontStyle; @@ -16,21 +16,19 @@ enum RNSVGFontVariantLigatures fontVariantLigatures; enum RNSVGTextAnchor textAnchor; enum RNSVGTextDecoration textDecoration; - double kerning; - double wordSpacing; - double letterSpacing; + CGFloat kerning; + CGFloat wordSpacing; + CGFloat letterSpacing; bool manualKerning; } + (instancetype)Defaults; -+ (double)toAbsoluteWithNSString:(NSString *)string - scale:(double)scale - fontSize:(double)fontSize; ++ (CGFloat)toAbsoluteWithNSString:(NSString *)string + fontSize:(CGFloat)fontSize; + (instancetype)initWithNSDictionary:(NSDictionary *)font - parent:(RNSVGFontData *)parent - scale:(double)scale; + parent:(RNSVGFontData *)parent; @end diff --git a/ios/Text/RNSVGFontData.m b/ios/Text/RNSVGFontData.m index 715d1eb8..cd843f8c 100644 --- a/ios/Text/RNSVGFontData.m +++ b/ios/Text/RNSVGFontData.m @@ -44,27 +44,21 @@ RNSVGFontData *RNSVGFontData_Defaults; return RNSVGFontData_Defaults; } -+ (double)toAbsoluteWithNSString:(NSString *)string - scale:(double)scale - fontSize:(double)fontSize { ++ (CGFloat)toAbsoluteWithNSString:(NSString *)string + fontSize:(CGFloat)fontSize { return [RNSVGPropHelper fromRelativeWithNSString:string relative:0 - offset:0 - scale:scale fontSize:fontSize]; } + (instancetype)initWithNSDictionary:(NSDictionary *)font - parent:(RNSVGFontData *)parent - scale:(double)scale { + parent:(RNSVGFontData *)parent { RNSVGFontData *data = [RNSVGFontData alloc]; - double parentFontSize = parent->fontSize; + CGFloat parentFontSize = parent->fontSize; if ([font objectForKey:FONT_SIZE]) { NSString *string = [font objectForKey:FONT_SIZE]; data->fontSize = [RNSVGPropHelper fromRelativeWithNSString:string relative:parentFontSize - offset:0 - scale:scale fontSize:parentFontSize]; } else { @@ -84,19 +78,27 @@ RNSVGFontData *RNSVGFontData_Defaults; data->textAnchor = anchor ? RNSVGTextAnchorFromString(anchor) : parent->textAnchor; NSString* decoration = [font objectForKey:TEXT_DECORATION]; data->textDecoration = decoration ? RNSVGTextDecorationFromString(decoration) : parent->textDecoration; + NSString* kerning = [font objectForKey:KERNING]; data->manualKerning = (kerning || parent->manualKerning ); - data->kerning = kerning ? [RNSVGFontData toAbsoluteWithNSString:kerning - scale:scale - fontSize:data->fontSize ] : parent->kerning; + CGFloat fontSize = data->fontSize; + data->kerning = kerning ? + [RNSVGFontData toAbsoluteWithNSString:kerning + fontSize:fontSize] + : parent->kerning; + NSString* wordSpacing = [font objectForKey:WORD_SPACING]; - data->wordSpacing = wordSpacing ? [RNSVGFontData toAbsoluteWithNSString:wordSpacing - scale:scale - fontSize:data->fontSize ] : parent->wordSpacing; + data->wordSpacing = wordSpacing ? + [RNSVGFontData toAbsoluteWithNSString:wordSpacing + fontSize:fontSize] + : parent->wordSpacing; + NSString* letterSpacing = [font objectForKey:LETTER_SPACING]; - data->letterSpacing = letterSpacing ? [RNSVGFontData toAbsoluteWithNSString:letterSpacing - scale:scale - fontSize:data->fontSize ] : parent->letterSpacing; + data->letterSpacing = letterSpacing ? + [RNSVGFontData toAbsoluteWithNSString:letterSpacing + fontSize:fontSize] + : parent->letterSpacing; + return data; } diff --git a/ios/Text/RNSVGGlyphContext.h b/ios/Text/RNSVGGlyphContext.h index a6944e25..723b12fc 100644 --- a/ios/Text/RNSVGGlyphContext.h +++ b/ios/Text/RNSVGGlyphContext.h @@ -10,27 +10,26 @@ - (CTFontRef)getGlyphFont; -- (instancetype)initWithScale:(float)scale_ - width:(float)width - height:(float)height; +- (instancetype)initWithWidth:(CGFloat)width + height:(CGFloat)height; - (RNSVGFontData *)getFont; -- (double)getFontSize; +- (CGFloat)getFontSize; -- (float)getHeight; +- (CGFloat)getHeight; -- (float)getWidth; +- (CGFloat)getWidth; -- (double)nextDeltaX; +- (CGFloat)nextDeltaX; -- (double)nextDeltaY; +- (CGFloat)nextDeltaY; -- (double)nextRotation; +- (CGFloat)nextRotation; -- (double)nextXWithDouble:(double)advance; +- (CGFloat)nextXWithDouble:(CGFloat)advance; -- (double)nextY; +- (CGFloat)nextY; - (void)popContext; diff --git a/ios/Text/RNSVGGlyphContext.m b/ios/Text/RNSVGGlyphContext.m index 52f0cb54..77f3d1ff 100644 --- a/ios/Text/RNSVGGlyphContext.m +++ b/ios/Text/RNSVGGlyphContext.m @@ -33,18 +33,18 @@ NSMutableArray *mRsIndices_; // Calculated on push context, percentage and em length depends on parent font size - double mFontSize_; + CGFloat mFontSize_; RNSVGFontData *topFont_; // Current accumulated values // https://www.w3.org/TR/SVG/types.html#DataTypeCoordinate // syntax is the same as that for - double mX_; - double mY_; + CGFloat mX_; + CGFloat mY_; // https://www.w3.org/TR/SVG/types.html#Length - double mDX_; - double mDY_; + CGFloat mDX_; + CGFloat mDY_; // Current SVGLengthList // https://www.w3.org/TR/SVG/types.html#InterfaceSVGLengthList @@ -89,9 +89,8 @@ long mTop_; // Constructor parameters - float mScale_; - float mWidth_; - float mHeight_; + CGFloat mWidth_; + CGFloat mHeight_; } - (void)pushContext:(RNSVGText*)node @@ -150,9 +149,8 @@ [self->mRsIndices_ addObject:[NSNumber numberWithLong:self->mRsIndex_]]; } -- (instancetype)initWithScale:(float)scale_ - width:(float)width - height:(float)height { +- (instancetype)initWithWidth:(CGFloat)width + height:(CGFloat)height { self->mFontContext_ = [[NSMutableArray alloc]init]; self->mXsContext_ = [[NSMutableArray alloc]init]; self->mYsContext_ = [[NSMutableArray alloc]init]; @@ -187,7 +185,6 @@ self->mDYIndex_ = -1; self->mRIndex_ = -1; - self->mScale_ = scale_; self->mWidth_ = width; self->mHeight_ = height; @@ -239,8 +236,7 @@ return; } RNSVGFontData *data = [RNSVGFontData initWithNSDictionary:font - parent:parent - scale:self->mScale_]; + parent:parent]; self->mFontSize_ = data->fontSize; [self->mFontContext_ addObject:data]; self->topFont_ = data; @@ -388,11 +384,11 @@ * Except for any additional information provided in this specification, * the normative definition of the property is in CSS2 ([CSS2], section 15.2.4). */ -- (double)getFontSize { +- (CGFloat)getFontSize { return mFontSize_; } -- (double)nextXWithDouble:(double)advance { +- (CGFloat)nextXWithDouble:(CGFloat)advance { [RNSVGGlyphContext incrementIndices:mXIndices_ topIndex:mXsIndex_]; long nextIndex = mXIndex_ + 1; if (nextIndex < [mXs_ count]) { @@ -407,7 +403,7 @@ return mX_; } -- (double)nextY { +- (CGFloat)nextY { [RNSVGGlyphContext incrementIndices:mYIndices_ topIndex:mYsIndex_]; long nextIndex = mYIndex_ + 1; if (nextIndex < [mYs_ count]) { @@ -421,13 +417,13 @@ return mY_; } -- (double)nextDeltaX { +- (CGFloat)nextDeltaX { [RNSVGGlyphContext incrementIndices:mDXIndices_ topIndex:mDXsIndex_]; long nextIndex = mDXIndex_ + 1; if (nextIndex < [mDXs_ count]) { mDXIndex_ = nextIndex; RNSVGLength *length = [mDXs_ objectAtIndex:nextIndex]; - double val = [RNSVGPropHelper fromRelative:length + CGFloat val = [RNSVGPropHelper fromRelative:length relative:mWidth_ fontSize:mFontSize_]; mDX_ += val; @@ -435,13 +431,13 @@ return mDX_; } -- (double)nextDeltaY { +- (CGFloat)nextDeltaY { [RNSVGGlyphContext incrementIndices:mDYIndices_ topIndex:mDYsIndex_]; long nextIndex = mDYIndex_ + 1; if (nextIndex < [mDYs_ count]) { mDYIndex_ = nextIndex; RNSVGLength *length = [mDYs_ objectAtIndex:nextIndex]; - double val = [RNSVGPropHelper fromRelative:length + CGFloat val = [RNSVGPropHelper fromRelative:length relative:mHeight_ fontSize:mFontSize_]; mDY_ += val; @@ -449,7 +445,7 @@ return mDY_; } -- (double)nextRotation { +- (CGFloat)nextRotation { [RNSVGGlyphContext incrementIndices:mRIndices_ topIndex:mRsIndex_]; long nextIndex = mRIndex_ + 1; long count = [mRs_ count]; @@ -461,11 +457,11 @@ return [mRs_[mRIndex_] value]; } -- (float)getWidth { +- (CGFloat)getWidth { return mWidth_; } -- (float)getHeight { +- (CGFloat)getHeight { return mHeight_; } @end diff --git a/ios/Text/RNSVGPropHelper.h b/ios/Text/RNSVGPropHelper.h index 2da917f5..ce89239e 100644 --- a/ios/Text/RNSVGPropHelper.h +++ b/ios/Text/RNSVGPropHelper.h @@ -7,18 +7,16 @@ @interface RNSVGPropHelper : NSObject -+ (double) fromRelativeWithNSString:(NSString *)length - relative:(double)relative - offset:(double)offset - scale:(double)scale - fontSize:(double)fontSize; ++ (CGFloat) fromRelativeWithNSString:(NSString *)length + relative:(CGFloat)relative + fontSize:(CGFloat)fontSize; -+ (double) fromRelative:(RNSVGLength*)length - relative:(double)relative - fontSize:(double)fontSize; ++ (CGFloat) fromRelative:(RNSVGLength*)length + relative:(CGFloat)relative + fontSize:(CGFloat)fontSize; -+ (double)fromRelative:(RNSVGLength*)length - relative:(double)relative; ++ (CGFloat)fromRelative:(RNSVGLength*)length + relative:(CGFloat)relative; @end #endif diff --git a/ios/Text/RNSVGPropHelper.m b/ios/Text/RNSVGPropHelper.m index 5d242c5b..f6fd319b 100644 --- a/ios/Text/RNSVGPropHelper.m +++ b/ios/Text/RNSVGPropHelper.m @@ -1,26 +1,24 @@ #include "RNSVGPropHelper.h" @implementation RNSVGPropHelper -+ (double)fromRelativeWithNSString:(NSString *)length - relative:(double)relative - offset:(double)offset - scale:(double)scale - fontSize:(double)fontSize { ++ (CGFloat)fromRelativeWithNSString:(NSString *)length + relative:(CGFloat)relative + fontSize:(CGFloat)fontSize { length = [length stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; NSUInteger stringLength = [length length]; NSInteger percentIndex = stringLength - 1; if (stringLength == 0) { - return offset; + return 0; } else if ([length characterAtIndex:percentIndex] == '%') { - return [[length substringWithRange:NSMakeRange(0, percentIndex)] doubleValue] / 100 * relative + offset; + return [[length substringWithRange:NSMakeRange(0, percentIndex)] doubleValue] / 100 * relative; } else { NSInteger twoLetterUnitIndex = stringLength - 2; if (twoLetterUnitIndex > 0) { NSString *lastTwo = [length substringFromIndex:twoLetterUnitIndex]; NSUInteger end = twoLetterUnitIndex; - double unit = 1; + CGFloat unit = 1; if ([lastTwo isEqualToString:@"px"]) { } else if ([lastTwo isEqualToString:@"em"]) { @@ -41,19 +39,19 @@ end = stringLength; } - return [[length substringWithRange:NSMakeRange(0, end)] doubleValue] * unit * scale + offset; + return [[length substringWithRange:NSMakeRange(0, end)] doubleValue] * unit; } else { - return [length doubleValue] * scale + offset; + return [length doubleValue]; } } } -+ (double)fromRelative:(RNSVGLength*)length - relative:(double)relative - fontSize:(double)fontSize { ++ (CGFloat)fromRelative:(RNSVGLength*)length + relative:(CGFloat)relative + fontSize:(CGFloat)fontSize { RNSVGLengthUnitType unitType = length.unit; - double value = length.value; - double unit = 1; + CGFloat value = length.value; + CGFloat unit = 1; switch (unitType) { case SVG_LENGTHTYPE_NUMBER: case SVG_LENGTHTYPE_PX: @@ -93,11 +91,11 @@ return value * unit; } -+ (double)fromRelative:(RNSVGLength*)length - relative:(double)relative { ++ (CGFloat)fromRelative:(RNSVGLength*)length + relative:(CGFloat)relative { RNSVGLengthUnitType unitType = length.unit; - double value = length.value; - double unit = 1; + CGFloat value = length.value; + CGFloat unit = 1; switch (unitType) { case SVG_LENGTHTYPE_NUMBER: case SVG_LENGTHTYPE_PX: diff --git a/ios/Text/RNSVGTSpan.m b/ios/Text/RNSVGTSpan.m index 5d868083..22d6ab46 100644 --- a/ios/Text/RNSVGTSpan.m +++ b/ios/Text/RNSVGTSpan.m @@ -12,7 +12,7 @@ #import "RNSVGFontData.h" static NSCharacterSet *RNSVGTSpan_separators = nil; -static double RNSVGTSpan_radToDeg = 180 / M_PI; +static CGFloat RNSVGTSpan_radToDeg = 180 / M_PI; @implementation RNSVGTSpan { @@ -119,9 +119,9 @@ static double RNSVGTSpan_radToDeg = 180 / M_PI; * or decrease the space between typographic character units in order to justify text. * * */ - double kerning = font->kerning; - double wordSpacing = font->wordSpacing; - double letterSpacing = font->letterSpacing; + CGFloat kerning = font->kerning; + CGFloat wordSpacing = font->wordSpacing; + CGFloat letterSpacing = font->letterSpacing; bool autoKerning = !font->manualKerning; /* @@ -285,15 +285,15 @@ static double RNSVGTSpan_radToDeg = 180 / M_PI; */ enum RNSVGTextAnchor textAnchor = font->textAnchor; CGRect textBounds = CTLineGetBoundsWithOptions(line, 0); - double textMeasure = CGRectGetWidth(textBounds); - double offset = [RNSVGTSpan getTextAnchorOffset:textAnchor width:textMeasure]; + CGFloat textMeasure = CGRectGetWidth(textBounds); + CGFloat offset = [RNSVGTSpan getTextAnchorOffset:textAnchor width:textMeasure]; bool hasTextPath = textPath != nil; int side = 1; - double startOfRendering = 0; - double endOfRendering = _pathLength; - double fontSize = [gc getFontSize]; + CGFloat startOfRendering = 0; + CGFloat endOfRendering = _pathLength; + CGFloat fontSize = [gc getFontSize]; bool sharpMidLine = false; if (hasTextPath) { sharpMidLine = RNSVGTextPathMidLineFromString([textPath midLine]) == RNSVGTextPathMidLineSharp; @@ -356,12 +356,12 @@ static double RNSVGTSpan_radToDeg = 180 / M_PI; a point on the path equal distance in both directions from the initial position on the path is reached. */ - double absoluteStartOffset = [RNSVGPropHelper fromRelative:textPath.startOffset + CGFloat absoluteStartOffset = [RNSVGPropHelper fromRelative:textPath.startOffset relative:_pathLength fontSize:fontSize]; offset += absoluteStartOffset; if (isClosed) { - double halfPathDistance = _pathLength / 2; + CGFloat halfPathDistance = _pathLength / 2; startOfRendering = absoluteStartOffset + (textAnchor == RNSVGTextAnchorMiddle ? -halfPathDistance : 0); endOfRendering = startOfRendering + _pathLength; } @@ -449,11 +449,11 @@ static double RNSVGTSpan_radToDeg = 180 / M_PI; the author's computation exactly matched the value calculated by the user agent; thus, no advance adjustments are made. */ - double scaleSpacingAndGlyphs = 1; + CGFloat scaleSpacingAndGlyphs = 1; RNSVGLength *mTextLength = [self textLength]; enum RNSVGTextLengthAdjust mLengthAdjust = RNSVGTextLengthAdjustFromString([self lengthAdjust]); if (mTextLength != nil) { - double author = [RNSVGPropHelper fromRelative:mTextLength + CGFloat author = [RNSVGPropHelper fromRelative:mTextLength relative:[gc getWidth] fontSize:fontSize]; if (author < 0) { @@ -474,7 +474,7 @@ static double RNSVGTSpan_radToDeg = 180 / M_PI; break; } } - double scaledDirection = scaleSpacingAndGlyphs * side; + CGFloat scaledDirection = scaleSpacingAndGlyphs * side; /* https://developer.mozilla.org/en/docs/Web/CSS/vertical-align @@ -503,8 +503,8 @@ static double RNSVGTSpan_radToDeg = 180 / M_PI; */ /* CGRect fontBounds = CTFontGetBoundingBox(fontRef); - double textHeight = CGRectGetHeight(textBounds); - double fontWidth = CGRectGetWidth(textBounds); + CGFloat textHeight = CGRectGetHeight(textBounds); + CGFloat fontWidth = CGRectGetWidth(textBounds); CGPoint fontOrigin = fontBounds.origin; CGFloat fontMinX = fontOrigin.x; @@ -513,12 +513,12 @@ static double RNSVGTSpan_radToDeg = 180 / M_PI; CGFloat fontMaxY = fontMinY + textHeight; */ // TODO - double descenderDepth = CTFontGetDescent(fontRef); - double bottom = descenderDepth + CTFontGetLeading(fontRef); - double ascenderHeight = CTFontGetAscent(fontRef); - double top = ascenderHeight; - double totalHeight = top + bottom; - double baselineShift = 0; + CGFloat descenderDepth = CTFontGetDescent(fontRef); + CGFloat bottom = descenderDepth + CTFontGetLeading(fontRef); + CGFloat ascenderHeight = CTFontGetAscent(fontRef); + CGFloat top = ascenderHeight; + CGFloat totalHeight = top + bottom; + CGFloat baselineShift = 0; NSString *baselineShiftString = self.baselineShift; enum RNSVGAlignmentBaseline baseline = RNSVGAlignmentBaselineFromString(self.alignmentBaseline); if (baseline != RNSVGAlignmentBaselineBaseline) { @@ -647,7 +647,7 @@ static double RNSVGTSpan_radToDeg = 180 / M_PI; NSDictionary* os2 = [tables objectForKey:@"os2"]; NSNumber* ySubscriptYOffset = [os2 objectForKey:@"ySubscriptYOffset"]; if (ySubscriptYOffset) { - double subOffset = [ySubscriptYOffset doubleValue]; + CGFloat subOffset = [ySubscriptYOffset doubleValue]; baselineShift += fontSize * subOffset / [unitsPerEm doubleValue]; } } else if (fontData != nil && [baselineShiftString isEqualToString:@"super"]) { @@ -657,15 +657,13 @@ static double RNSVGTSpan_radToDeg = 180 / M_PI; NSDictionary* os2 = [tables objectForKey:@"os2"]; NSNumber* ySuperscriptYOffset = [os2 objectForKey:@"ySuperscriptYOffset"]; if (ySuperscriptYOffset) { - double superOffset = [ySuperscriptYOffset doubleValue]; + CGFloat superOffset = [ySuperscriptYOffset doubleValue]; baselineShift -= fontSize * superOffset / [unitsPerEm doubleValue]; } } else if ([baselineShiftString isEqualToString:@"baseline"]) { } else { baselineShift -= [RNSVGPropHelper fromRelativeWithNSString:baselineShiftString relative:fontSize - offset:0 - scale:1 fontSize:fontSize]; } break; @@ -715,15 +713,15 @@ static double RNSVGTSpan_radToDeg = 180 / M_PI; CFIndex currIndex = indices[g]; char currentChar = [str characterAtIndex:currIndex]; bool isWordSeparator = [RNSVGTSpan_separators characterIsMember:currentChar]; - double wordSpace = isWordSeparator ? wordSpacing : 0; - double spacing = wordSpace + letterSpacing; - double advance = charWidth + spacing; + CGFloat wordSpace = isWordSeparator ? wordSpacing : 0; + CGFloat spacing = wordSpace + letterSpacing; + CGFloat advance = charWidth + spacing; - double x = [gc nextXWithDouble:kerning + advance]; - double y = [gc nextY]; - double dx = [gc nextDeltaX]; - double dy = [gc nextDeltaY]; - double r = [gc nextRotation] / RNSVGTSpan_radToDeg; + CGFloat x = [gc nextXWithDouble:kerning + advance]; + CGFloat y = [gc nextY]; + CGFloat dx = [gc nextDeltaX]; + CGFloat dy = [gc nextDeltaY]; + CGFloat r = [gc nextRotation] / RNSVGTSpan_radToDeg; if (isWordSeparator) { continue; @@ -743,8 +741,8 @@ static double RNSVGTSpan_radToDeg = 180 / M_PI; advance *= side; charWidth *= side; - double cursor = offset + (x + dx) * side; - double startPoint = cursor - advance; + CGFloat cursor = offset + (x + dx) * side; + CGFloat startPoint = cursor - advance; CGAffineTransform transform = CGAffineTransformIdentity; if (hasTextPath) { @@ -754,15 +752,15 @@ static double RNSVGTSpan_radToDeg = 180 / M_PI; distance along the path algorithm. This point is the endpoint-on-the-path for the glyph. */ - // TODO double endPoint = startPoint + charWidth; + // TODO CGFloat endPoint = startPoint + charWidth; /* Determine the midpoint-on-the-path, which is the point on the path which is "halfway" (user agents can choose either a distance calculation or a parametric calculation) between the startpoint-on-the-path and the endpoint-on-the-path. */ - double halfWay = charWidth / 2; - double midPoint = startPoint + halfWay; + CGFloat halfWay = charWidth / 2; + CGFloat midPoint = startPoint + halfWay; // Glyphs whose midpoint-on-the-path are off the path are not rendered. if (midPoint > endOfRendering) { @@ -831,8 +829,8 @@ static double RNSVGTSpan_radToDeg = 180 / M_PI; CGSize measuredSize = [currChars sizeWithAttributes: @{NSFontAttributeName:customFont}]; label.font = customFont; - double width = ceilf(measuredSize.width); - double height = ceilf(measuredSize.height); + CGFloat width = ceilf(measuredSize.width); + CGFloat height = ceilf(measuredSize.height); CGRect bounds = CGRectMake(0, 0, width, height); label.frame = bounds; diff --git a/ios/Text/RNSVGText.m b/ios/Text/RNSVGText.m index 7f179d16..0af35833 100644 --- a/ios/Text/RNSVGText.m +++ b/ios/Text/RNSVGText.m @@ -144,10 +144,8 @@ { CGRect bounds = CGContextGetClipBoundingBox(context); CGSize size = bounds.size; - _glyphContext = [[RNSVGGlyphContext alloc] - initWithScale:1 - width:size.width - height:size.height]; + _glyphContext = [[RNSVGGlyphContext alloc] initWithWidth:size.width + height:size.height]; } - (CGPathRef)getGroupPath:(CGContextRef)context diff --git a/ios/Utils/RCTConvert+RNSVG.h b/ios/Utils/RCTConvert+RNSVG.h index c225ef00..b773f00c 100644 --- a/ios/Utils/RCTConvert+RNSVG.h +++ b/ios/Utils/RCTConvert+RNSVG.h @@ -9,7 +9,6 @@ #import #import #import "RCTConvert+RNSVG.h" -#import "RNSVGCGFloatArray.h" #import #import "RNSVGCGFCRule.h" #import "RNSVGVBMOS.h" @@ -26,7 +25,6 @@ + (RNSVGCGFCRule)RNSVGCGFCRule:(id)json; + (RNSVGVBMOS)RNSVGVBMOS:(id)json; + (RNSVGUnits)RNSVGUnits:(id)json; -+ (RNSVGCGFloatArray)RNSVGCGFloatArray:(id)json; + (RNSVGBrush *)RNSVGBrush:(id)json; + (RNSVGPathParser *)RNSVGCGPath:(NSString *)d; + (CGRect)RNSVGCGRect:(id)json offset:(NSUInteger)offset; diff --git a/ios/Utils/RCTConvert+RNSVG.m b/ios/Utils/RCTConvert+RNSVG.m index a6b9cfd6..428bb934 100644 --- a/ios/Utils/RCTConvert+RNSVG.m +++ b/ios/Utils/RCTConvert+RNSVG.m @@ -33,21 +33,19 @@ RCT_ENUM_CONVERTER(RNSVGUnits, (@{ @"userSpaceOnUse": @(kRNSVGUnitsUserSpaceOnUse), }), kRNSVGUnitsObjectBoundingBox, intValue) -+ (RNSVGCGFloatArray)RNSVGCGFloatArray:(id)json ++ (CGFloat*)RNSVGCGFloatArray:(id)json { NSArray *arr = [self NSNumberArray:json]; NSUInteger count = arr.count; - RNSVGCGFloatArray array; - array.count = count; - array.array = nil; + CGFloat* array = nil; if (count) { // Ideally, these arrays should already use the same memory layout. // In that case we shouldn't need this new malloc. - array.array = malloc(sizeof(CGFloat) * count); + array = malloc(sizeof(CGFloat) * count); for (NSUInteger i = 0; i < count; i++) { - array.array[i] = [arr[i] doubleValue]; + array[i] = [arr[i] doubleValue]; } } @@ -62,7 +60,7 @@ RCT_ENUM_CONVERTER(RNSVGUnits, (@{ RNSVGDigitRegEx = [NSRegularExpression regularExpressionWithPattern:@"[0-9.-]+" options:NSRegularExpressionCaseInsensitive error:nil]; } NSArray *_matches = [RNSVGDigitRegEx matchesInString:value options:0 range:NSMakeRange(0, [value length])]; - NSMutableArray *output = [NSMutableArray array]; + NSMutableArray *output = [NSMutableArray array]; NSUInteger i = 0; [output addObject:[NSNumber numberWithInteger:0]]; for (NSTextCheckingResult *match in _matches) { @@ -161,20 +159,20 @@ RCT_ENUM_CONVERTER(RNSVGUnits, (@{ return nil; } arr = [arr subarrayWithRange:(NSRange){offset, arr.count - offset}]; - RNSVGCGFloatArray colorsAndOffsets = [self RNSVGCGFloatArray:arr]; - size_t stops = colorsAndOffsets.count / 5; + CGFloat* colorsAndOffsets = [self RNSVGCGFloatArray:arr]; + size_t stops = arr.count / 5; CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB(); CGGradientRef gradient = CGGradientCreateWithColorComponents( rgb, - colorsAndOffsets.array, - colorsAndOffsets.array + stops * 4, + colorsAndOffsets, + colorsAndOffsets + stops * 4, stops ); CGColorSpaceRelease(rgb); - free(colorsAndOffsets.array); + free(colorsAndOffsets); return (CGGradientRef)CFAutorelease(gradient); } diff --git a/ios/Utils/RNSVGCGFloatArray.h b/ios/Utils/RNSVGCGFloatArray.h deleted file mode 100644 index 76a7fb58..00000000 --- a/ios/Utils/RNSVGCGFloatArray.h +++ /dev/null @@ -1,19 +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. - */ - -// A little helper to make sure we have the right memory allocation ready for use. -// We assume that we will only this in one place so no reference counting is necessary. -// Needs to be freed when dealloced. - -// This is fragile since this relies on these values not getting reused. Consider -// wrapping these in an Obj-C class or some ARC hackery to get refcounting. - -typedef struct { - size_t count; - CGFloat *array; -} RNSVGCGFloatArray; diff --git a/ios/Utils/RNSVGLength.h b/ios/Utils/RNSVGLength.h index a446d5ed..5a4af640 100644 --- a/ios/Utils/RNSVGLength.h +++ b/ios/Utils/RNSVGLength.h @@ -1,3 +1,5 @@ +#import + #ifndef RNSVGLength_h #define RNSVGLength_h @@ -18,10 +20,10 @@ typedef CF_ENUM(unsigned short, RNSVGLengthUnitType) { @interface RNSVGLength : NSObject -@property (nonatomic, assign) double value; +@property (nonatomic, assign) CGFloat value; @property (nonatomic, assign) RNSVGLengthUnitType unit; -+ (instancetype) lengthWithNumber: (double) number; ++ (instancetype) lengthWithNumber: (CGFloat) number; + (instancetype) lengthWithString: (NSString *) lengthString; - (BOOL) isEqualTo: (RNSVGLength *)other; diff --git a/ios/Utils/RNSVGLength.m b/ios/Utils/RNSVGLength.m index bb4d7324..f4dfd8ce 100644 --- a/ios/Utils/RNSVGLength.m +++ b/ios/Utils/RNSVGLength.m @@ -14,7 +14,7 @@ return self; } -+ (instancetype) lengthWithNumber: (double) number ++ (instancetype) lengthWithNumber:(CGFloat)number { RNSVGLength *length = [[self alloc] init]; length.unit = SVG_LENGTHTYPE_NUMBER; diff --git a/ios/Utils/RNSVGPercentageConverter.m b/ios/Utils/RNSVGPercentageConverter.m index 81505c29..b86c9f85 100644 --- a/ios/Utils/RNSVGPercentageConverter.m +++ b/ios/Utils/RNSVGPercentageConverter.m @@ -22,7 +22,7 @@ static NSRegularExpression* percentageRegExp; if (string == nil) { return offset; } else if (![self isPercentage:string]) { - return [string floatValue] + offset; + return [string doubleValue] + offset; } else { return [self percentageToFloat:string relative:relative offset:offset]; } @@ -49,7 +49,7 @@ static NSRegularExpression* percentageRegExp; usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { - matched = [[percentage substringWithRange:NSMakeRange(result.range.location, result.range.length)] floatValue]; + matched = [[percentage substringWithRange:NSMakeRange(result.range.location, result.range.length)] doubleValue]; matched = matched / 100 * relative + offset; }]; diff --git a/ios/ViewManagers/RNSVGTextManager.m b/ios/ViewManagers/RNSVGTextManager.m index cfb6e8c3..93d8e536 100644 --- a/ios/ViewManagers/RNSVGTextManager.m +++ b/ios/ViewManagers/RNSVGTextManager.m @@ -62,7 +62,7 @@ RCT_CUSTOM_VIEW_PROPERTY(baselineShift, id, RNSVGText) NSString *stringValue = (NSString *)json; view.baselineShift = stringValue; } else { - view.baselineShift = [NSString stringWithFormat:@"%f", [json floatValue]]; + view.baselineShift = [NSString stringWithFormat:@"%f", [json doubleValue]]; } } RCT_EXPORT_VIEW_PROPERTY(lengthAdjust, NSString)