[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.
This commit is contained in:
Mikael Sand
2018-10-20 20:46:04 +03:00
parent f5f2c52f88
commit 9fe9e2d5b3
22 changed files with 212 additions and 241 deletions
+18 -18
View File
@@ -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
+2 -2
View File
@@ -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
-2
View File
@@ -176,7 +176,6 @@
1039D2901CE71EC2001E90A8 /* RNSVGText.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGText.m; path = Text/RNSVGText.m; sourceTree = "<group>"; };
1039D29B1CE72177001E90A8 /* RCTConvert+RNSVG.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "RCTConvert+RNSVG.h"; path = "Utils/RCTConvert+RNSVG.h"; sourceTree = "<group>"; };
1039D29C1CE72177001E90A8 /* RCTConvert+RNSVG.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "RCTConvert+RNSVG.m"; path = "Utils/RCTConvert+RNSVG.m"; sourceTree = "<group>"; };
1039D29E1CE72177001E90A8 /* RNSVGCGFloatArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGCGFloatArray.h; path = Utils/RNSVGCGFloatArray.h; sourceTree = "<group>"; };
1039D2A11CE721A7001E90A8 /* RNSVGContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGContainer.h; sourceTree = "<group>"; };
1039D2AE1CE72F27001E90A8 /* RNSVGPercentageConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGPercentageConverter.h; path = Utils/RNSVGPercentageConverter.h; sourceTree = "<group>"; };
1039D2AF1CE72F27001E90A8 /* RNSVGPercentageConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGPercentageConverter.m; path = Utils/RNSVGPercentageConverter.m; sourceTree = "<group>"; };
@@ -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 */,
+2
View File
@@ -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;
+19 -20
View File
@@ -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];
-1
View File
@@ -9,7 +9,6 @@
#import <Foundation/Foundation.h>
#import "RNSVGBrush.h"
#import "RNSVGCGFloatArray.h"
#import "RNSVGCGFCRule.h"
#import "RNSVGNode.h"
#import "RNSVGLength.h"
+29 -22
View File
@@ -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<RNSVGLength *> *)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) {
+7 -9
View File
@@ -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
+21 -19
View File
@@ -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;
}
+10 -11
View File
@@ -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;
+20 -24
View File
@@ -33,18 +33,18 @@
NSMutableArray<NSNumber*> *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
// <coordinate> syntax is the same as that for <length>
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 <list-of-coordinates> 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
+8 -10
View File
@@ -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
+17 -19
View File
@@ -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:
+39 -41
View File
@@ -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;
+2 -4
View File
@@ -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
-2
View File
@@ -9,7 +9,6 @@
#import <QuartzCore/QuartzCore.h>
#import <CoreText/CoreText.h>
#import "RCTConvert+RNSVG.h"
#import "RNSVGCGFloatArray.h"
#import <React/RCTConvert.h>
#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;
+10 -12
View File
@@ -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<NSTextCheckingResult*> *_matches = [RNSVGDigitRegEx matchesInString:value options:0 range:NSMakeRange(0, [value length])];
NSMutableArray *output = [NSMutableArray array];
NSMutableArray<NSNumber*> *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);
}
-19
View File
@@ -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;
+4 -2
View File
@@ -1,3 +1,5 @@
#import <UIKit/UIKit.h>
#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;
+1 -1
View File
@@ -14,7 +14,7 @@
return self;
}
+ (instancetype) lengthWithNumber: (double) number
+ (instancetype) lengthWithNumber:(CGFloat)number
{
RNSVGLength *length = [[self alloc] init];
length.unit = SVG_LENGTHTYPE_NUMBER;
+2 -2
View File
@@ -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;
}];
+1 -1
View File
@@ -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)