mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-02 14:50:43 +00:00
Implement basic support for Pattern element
This commit is contained in:
@@ -10,14 +10,21 @@
|
||||
#import "RNSVGBrushType.h"
|
||||
#import "RNSVGUnits.h"
|
||||
|
||||
@class RNSVGPattern;
|
||||
|
||||
@interface RNSVGPainter : NSObject
|
||||
|
||||
@property (nonatomic, assign) RNSVGPattern* pattern;
|
||||
@property (nonatomic, assign) CGRect paintBounds;
|
||||
|
||||
- (instancetype)initWithPointsArray:(NSArray<NSString *> *)pointsArray NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
- (void)paint:(CGContextRef)context bounds:(CGRect)bounds;
|
||||
|
||||
- (void)setUnits:(RNSVGUnits)unit;
|
||||
|
||||
- (void)setContentUnits:(RNSVGUnits)unit;
|
||||
|
||||
- (void)setUserSpaceBoundingBox:(CGRect)userSpaceBoundingBox;
|
||||
|
||||
- (void)setTransform:(CGAffineTransform)transform;
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
*/
|
||||
|
||||
#import "RNSVGPainter.h"
|
||||
#import "RNSVGPattern.h"
|
||||
#import "RNSVGPercentageConverter.h"
|
||||
#import "RNSVGViewBox.h"
|
||||
|
||||
@implementation RNSVGPainter
|
||||
{
|
||||
@@ -15,6 +17,7 @@
|
||||
NSArray<NSNumber *> *_colors;
|
||||
RNSVGBrushType _type;
|
||||
BOOL _useObjectBoundingBox;
|
||||
BOOL _useContentObjectBoundingBox;
|
||||
CGAffineTransform _transform;
|
||||
CGRect _userSpaceBoundingBox;
|
||||
}
|
||||
@@ -34,6 +37,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
_useObjectBoundingBox = unit == kRNSVGUnitsObjectBoundingBox;
|
||||
}
|
||||
|
||||
- (void)setContentUnits:(RNSVGUnits)unit
|
||||
{
|
||||
_useContentObjectBoundingBox = unit == kRNSVGUnitsObjectBoundingBox;
|
||||
}
|
||||
|
||||
- (void)setUserSpaceBoundingBox:(CGRect)userSpaceBoundingBox
|
||||
{
|
||||
_userSpaceBoundingBox = userSpaceBoundingBox;
|
||||
@@ -44,6 +52,17 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
_transform = transform;
|
||||
}
|
||||
|
||||
- (void)setPattern:(RNSVGPattern *)pattern
|
||||
{
|
||||
if (_type != kRNSVGUndefinedType) {
|
||||
// todo: throw error
|
||||
return;
|
||||
}
|
||||
|
||||
_type = kRNSVGPattern;
|
||||
_pattern = pattern;
|
||||
}
|
||||
|
||||
- (void)setLinearGradientColors:(NSArray<NSNumber *> *)colors
|
||||
{
|
||||
if (_type != kRNSVGUndefinedType) {
|
||||
@@ -73,7 +92,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
} else if (_type == kRNSVGRadialGradient) {
|
||||
[self paintRidialGradient:context bounds:(CGRect)bounds];
|
||||
} else if (_type == kRNSVGPattern) {
|
||||
// todo:
|
||||
[self paintPattern:context bounds:(CGRect)bounds];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +112,67 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
return CGRectMake(x, y, width, height);
|
||||
}
|
||||
|
||||
void PatternFunction(void* info, CGContextRef context)
|
||||
{
|
||||
RNSVGPainter *_painter = (__bridge RNSVGPainter *)info;
|
||||
RNSVGPattern *_pattern = [_painter pattern];
|
||||
CGRect rect = _painter.paintBounds;
|
||||
|
||||
CGAffineTransform _viewBoxTransform = [RNSVGViewBox getTransform:CGRectMake(_pattern.minX, _pattern.minY, _pattern.vbWidth, _pattern.vbHeight)
|
||||
eRect:rect
|
||||
align:_pattern.align
|
||||
meetOrSlice:_pattern.meetOrSlice];
|
||||
CGContextConcatCTM(context, _viewBoxTransform);
|
||||
|
||||
[_pattern renderTo:context rect:rect];
|
||||
}
|
||||
|
||||
- (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 x = [RNSVGPercentageConverter stringToFloat:(NSString *)[_points objectAtIndex:0]
|
||||
relative:width
|
||||
offset:offsetX];
|
||||
CGFloat y = [RNSVGPercentageConverter stringToFloat:(NSString *)[_points objectAtIndex:1]
|
||||
relative:height
|
||||
offset:offsetY];
|
||||
CGFloat w = [RNSVGPercentageConverter stringToFloat:(NSString *)[_points objectAtIndex:2]
|
||||
relative:width
|
||||
offset:offsetX];
|
||||
CGFloat h = [RNSVGPercentageConverter stringToFloat:(NSString *)[_points objectAtIndex:3]
|
||||
relative:height
|
||||
offset:offsetY];
|
||||
|
||||
CGAffineTransform viewbox = [self.pattern.svgView getViewBoxTransform];
|
||||
CGRect newBounds = CGRectApplyAffineTransform(CGRectMake(x, y, w, h), viewbox);
|
||||
CGSize size = newBounds.size;
|
||||
self.paintBounds = newBounds;
|
||||
|
||||
const CGPatternCallbacks callbacks = { 0, &PatternFunction, NULL };
|
||||
CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(NULL);
|
||||
CGContextSetFillColorSpace(context, patternSpace);
|
||||
CGColorSpaceRelease(patternSpace);
|
||||
|
||||
CGPatternRef pattern = CGPatternCreate((__bridge void * _Nullable)(self),
|
||||
newBounds,
|
||||
CGAffineTransformIdentity,
|
||||
size.width,
|
||||
size.height,
|
||||
kCGPatternTilingConstantSpacing,
|
||||
true,
|
||||
&callbacks);
|
||||
CGFloat alpha = 1.0;
|
||||
CGContextSetFillPattern(context, pattern, &alpha);
|
||||
CGPatternRelease(pattern);
|
||||
|
||||
CGContextFillRect(context, bounds);
|
||||
}
|
||||
|
||||
- (void)paintLinearGradient:(CGContextRef)context bounds:(CGRect)bounds
|
||||
{
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Horcrux.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the MIT-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RNSVGPattern.h"
|
||||
|
||||
#import "RCTConvert+RNSVG.h"
|
||||
#import <React/RCTLog.h>
|
||||
|
||||
@implementation RNSVGPattern
|
||||
{
|
||||
CGImageRef _image;
|
||||
CGRect _rect;
|
||||
}
|
||||
|
||||
- (instancetype)initWithArray:(NSArray<id /* imagesource + numbers */> *)array
|
||||
{
|
||||
if ((self = [super initWithArray:array])) {
|
||||
if (array.count < 6) {
|
||||
RCTLogError(@"-[%@ %@] expects 6 elements, received %@",
|
||||
self.class, NSStringFromSelector(_cmd), array);
|
||||
return nil;
|
||||
}
|
||||
_image = CGImageRetain([RCTConvert CGImage:array[1]]);
|
||||
_rect = [RCTConvert RNSVGCGRect:array offset:2];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGImageRelease(_image);
|
||||
}
|
||||
|
||||
// Note: This could use applyFillColor with a pattern. This could be more efficient but
|
||||
// to do that, we need to calculate our own user space CTM.
|
||||
|
||||
- (void)paint:(CGContextRef)context opacity:(CGFloat)opacity brushConverter:(RNSVGPainter *)brushConverter;
|
||||
{
|
||||
CGContextDrawTiledImage(context, _rect, _image);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Horcrux.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the MIT-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
#import "RNSVGPattern.h"
|
||||
#import "RNSVGPainter.h"
|
||||
#import "RNSVGBrushType.h"
|
||||
#import "RNSVGNode.h"
|
||||
|
||||
@implementation RNSVGPattern
|
||||
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)parseReference
|
||||
{
|
||||
NSArray<NSString *> *points = @[self.x, self.y, self.patternwidth, self.patternheight];
|
||||
RNSVGPainter *painter = [[RNSVGPainter alloc] initWithPointsArray:points];
|
||||
[painter setUnits:self.patternUnits];
|
||||
[painter setContentUnits:self.patternContentUnits];
|
||||
[painter setTransform:self.patternTransform];
|
||||
[painter setPattern:self];
|
||||
|
||||
if (self.patternUnits == kRNSVGUnitsUserSpaceOnUse || self.patternContentUnits == kRNSVGUnitsUserSpaceOnUse) {
|
||||
[painter setUserSpaceBoundingBox:[self.svgView getContextBounds]];
|
||||
}
|
||||
|
||||
[self.svgView definePainter:painter painterName:self.name];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -54,4 +54,6 @@
|
||||
|
||||
- (void)drawToContext:(CGContextRef)context withRect:(CGRect)rect;
|
||||
|
||||
- (CGAffineTransform)getViewBoxTransform;
|
||||
|
||||
@end
|
||||
|
||||
@@ -268,4 +268,9 @@
|
||||
return CGContextGetClipBoundingBox(UIGraphicsGetCurrentContext());
|
||||
}
|
||||
|
||||
- (CGAffineTransform)getViewBoxTransform
|
||||
{
|
||||
return _viewBoxTransform;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -58,6 +58,10 @@
|
||||
7FC260CE1E3499BC00A39833 /* RNSVGViewBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FC260CD1E3499BC00A39833 /* RNSVGViewBox.m */; };
|
||||
7FC260D11E34A12000A39833 /* RNSVGSymbol.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FC260D01E34A12000A39833 /* RNSVGSymbol.m */; };
|
||||
7FC260D41E34A12A00A39833 /* RNSVGSymbolManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FC260D31E34A12A00A39833 /* RNSVGSymbolManager.m */; };
|
||||
94241666213B0D4500088E93 /* RNSVGPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 94241665213B0D4500088E93 /* RNSVGPattern.m */; };
|
||||
94241667213B0D4500088E93 /* RNSVGPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 94241665213B0D4500088E93 /* RNSVGPattern.m */; };
|
||||
9424166D213B302600088E93 /* RNSVGPatternManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9424166C213B302600088E93 /* RNSVGPatternManager.m */; };
|
||||
9424166E213B302600088E93 /* RNSVGPatternManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9424166C213B302600088E93 /* RNSVGPatternManager.m */; };
|
||||
9494C4D81F473BA700D5BCFD /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9494C4D71F473BA700D5BCFD /* QuartzCore.framework */; };
|
||||
9494C4DA1F473BCB00D5BCFD /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9494C4D91F473BCB00D5BCFD /* CoreText.framework */; };
|
||||
9494C4DC1F473BD900D5BCFD /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9494C4DB1F473BD900D5BCFD /* CoreGraphics.framework */; };
|
||||
@@ -238,6 +242,10 @@
|
||||
7FC260D01E34A12000A39833 /* RNSVGSymbol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGSymbol.m; path = Elements/RNSVGSymbol.m; sourceTree = "<group>"; };
|
||||
7FC260D21E34A12A00A39833 /* RNSVGSymbolManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGSymbolManager.h; sourceTree = "<group>"; };
|
||||
7FC260D31E34A12A00A39833 /* RNSVGSymbolManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGSymbolManager.m; sourceTree = "<group>"; };
|
||||
94241665213B0D4500088E93 /* RNSVGPattern.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = RNSVGPattern.m; path = Elements/RNSVGPattern.m; sourceTree = "<group>"; };
|
||||
94241669213B0DB800088E93 /* RNSVGPattern.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNSVGPattern.h; sourceTree = "<group>"; };
|
||||
9424166A213B2FF100088E93 /* RNSVGPatternManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNSVGPatternManager.h; sourceTree = "<group>"; };
|
||||
9424166C213B302600088E93 /* RNSVGPatternManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNSVGPatternManager.m; sourceTree = "<group>"; };
|
||||
9494C4D71F473BA700D5BCFD /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||
9494C4D91F473BCB00D5BCFD /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
|
||||
9494C4DB1F473BD900D5BCFD /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
|
||||
@@ -334,6 +342,8 @@
|
||||
7F08CE971E23476900650F83 /* RNSVGTextPathManager.m */,
|
||||
7F08CE981E23476900650F83 /* RNSVGTSpanManager.h */,
|
||||
7F08CE991E23476900650F83 /* RNSVGTSpanManager.m */,
|
||||
9424166A213B2FF100088E93 /* RNSVGPatternManager.h */,
|
||||
9424166C213B302600088E93 /* RNSVGPatternManager.m */,
|
||||
10BEC1BE1D3F680F00FDCB19 /* RNSVGLinearGradientManager.h */,
|
||||
10BEC1BF1D3F680F00FDCB19 /* RNSVGLinearGradientManager.m */,
|
||||
10BEC1C01D3F680F00FDCB19 /* RNSVGRadialGradientManager.h */,
|
||||
@@ -413,6 +423,8 @@
|
||||
7FC260D01E34A12000A39833 /* RNSVGSymbol.m */,
|
||||
10BEC1B81D3F66F500FDCB19 /* RNSVGLinearGradient.h */,
|
||||
10BEC1B91D3F66F500FDCB19 /* RNSVGLinearGradient.m */,
|
||||
94241669213B0DB800088E93 /* RNSVGPattern.h */,
|
||||
94241665213B0D4500088E93 /* RNSVGPattern.m */,
|
||||
10BEC1BA1D3F66F500FDCB19 /* RNSVGRadialGradient.h */,
|
||||
10BEC1BB1D3F66F500FDCB19 /* RNSVGRadialGradient.m */,
|
||||
1023B4911D3DF5060051496D /* RNSVGUse.h */,
|
||||
@@ -543,6 +555,7 @@
|
||||
B56895AA20352B36004DBF1E /* RNSVGBezierElement.m in Sources */,
|
||||
10BA0D3F1CE74E3100887C2B /* RNSVGTextManager.m in Sources */,
|
||||
1039D28A1CE71EB7001E90A8 /* RNSVGImage.m in Sources */,
|
||||
94241666213B0D4500088E93 /* RNSVGPattern.m in Sources */,
|
||||
10BA0D4B1CE74E3D00887C2B /* RNSVGRect.m in Sources */,
|
||||
10BA0D341CE74E3100887C2B /* RNSVGCircleManager.m in Sources */,
|
||||
10BEC1BC1D3F66F500FDCB19 /* RNSVGLinearGradient.m in Sources */,
|
||||
@@ -580,6 +593,7 @@
|
||||
7FC260D41E34A12A00A39833 /* RNSVGSymbolManager.m in Sources */,
|
||||
7F9CDAFA1E1F809C00E0C805 /* RNSVGPathParser.m in Sources */,
|
||||
10BA0D361CE74E3100887C2B /* RNSVGGroupManager.m in Sources */,
|
||||
9424166D213B302600088E93 /* RNSVGPatternManager.m in Sources */,
|
||||
7F08CE9A1E23476900650F83 /* RNSVGTextPathManager.m in Sources */,
|
||||
7F08CE9B1E23476900650F83 /* RNSVGTSpanManager.m in Sources */,
|
||||
B56895B120352B9C004DBF1E /* RNSVGPropHelper.m in Sources */,
|
||||
@@ -601,6 +615,7 @@
|
||||
A361E76E1EB0C33D00646005 /* RNSVGTextManager.m in Sources */,
|
||||
A361E76F1EB0C33D00646005 /* RNSVGImage.m in Sources */,
|
||||
A361E7701EB0C33D00646005 /* RNSVGRect.m in Sources */,
|
||||
94241667213B0D4500088E93 /* RNSVGPattern.m in Sources */,
|
||||
A361E7711EB0C33D00646005 /* RNSVGCircleManager.m in Sources */,
|
||||
A361E7721EB0C33D00646005 /* RNSVGLinearGradient.m in Sources */,
|
||||
A361E7731EB0C33D00646005 /* RNSVGPercentageConverter.m in Sources */,
|
||||
@@ -638,6 +653,7 @@
|
||||
A361E7921EB0C33D00646005 /* RNSVGSymbolManager.m in Sources */,
|
||||
A361E7931EB0C33D00646005 /* RNSVGPathParser.m in Sources */,
|
||||
A361E7941EB0C33D00646005 /* RNSVGGroupManager.m in Sources */,
|
||||
9424166E213B302600088E93 /* RNSVGPatternManager.m in Sources */,
|
||||
A361E7951EB0C33D00646005 /* RNSVGTextPathManager.m in Sources */,
|
||||
167AF45B2087C2A10035AA75 /* RNSVGTextProperties.m in Sources */,
|
||||
A361E7961EB0C33D00646005 /* RNSVGTSpanManager.m in Sources */,
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
#import "RNSVGGroup.h"
|
||||
|
||||
@interface RNSVGPattern : RNSVGGroup
|
||||
|
||||
@property (nonatomic, strong) NSString *x;
|
||||
@property (nonatomic, strong) NSString *y;
|
||||
@property (nonatomic, strong) NSString *patternwidth;
|
||||
@property (nonatomic, strong) NSString *patternheight;
|
||||
@property (nonatomic, assign)RNSVGUnits patternUnits;
|
||||
@property (nonatomic, assign)RNSVGUnits patternContentUnits;
|
||||
@property (nonatomic, assign)CGAffineTransform patternTransform;
|
||||
|
||||
@property (nonatomic, assign) CGFloat minX;
|
||||
@property (nonatomic, assign) CGFloat minY;
|
||||
@property (nonatomic, assign) CGFloat vbWidth;
|
||||
@property (nonatomic, assign) CGFloat vbHeight;
|
||||
@property (nonatomic, strong) NSString *align;
|
||||
@property (nonatomic, assign) RNSVGVBMOS meetOrSlice;
|
||||
|
||||
@end
|
||||
@@ -6,8 +6,8 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RNSVGBrush.h"
|
||||
#import "RNSVGGroupManager.h"
|
||||
|
||||
@interface RNSVGPattern : RNSVGBrush
|
||||
@interface RNSVGPatternManager : RNSVGGroupManager
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Horcrux.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the MIT-style license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RNSVGPatternManager.h"
|
||||
#import "RNSVGPattern.h"
|
||||
|
||||
@implementation RNSVGPatternManager
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (RNSVGPattern *)node
|
||||
{
|
||||
return [RNSVGPattern new];
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(x, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(y, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(patternwidth, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(patternheight, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(patternUnits, RNSVGUnits)
|
||||
RCT_EXPORT_VIEW_PROPERTY(patternContentUnits, RNSVGUnits)
|
||||
RCT_EXPORT_VIEW_PROPERTY(patternTransform, CGAffineTransform)
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(minX, CGFloat)
|
||||
RCT_EXPORT_VIEW_PROPERTY(minY, CGFloat)
|
||||
RCT_EXPORT_VIEW_PROPERTY(vbWidth, CGFloat)
|
||||
RCT_EXPORT_VIEW_PROPERTY(vbHeight, CGFloat)
|
||||
RCT_EXPORT_VIEW_PROPERTY(align, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(meetOrSlice, RNSVGVBMOS)
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user