mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-04 15:44:24 +00:00
Merge remote-tracking branch 'msand/NestedSvg' into merge-test
# Conflicts: # ios/Elements/RNSVGGroup.m # ios/RNSVGNode.h # ios/RNSVGNode.m
This commit is contained in:
@@ -19,7 +19,9 @@
|
||||
- (void)parseReference
|
||||
{
|
||||
[self traverseSubviews:^(RNSVGNode *node) {
|
||||
[node parseReference];
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
[node parseReference];
|
||||
}
|
||||
return YES;
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
|
||||
@property (nonatomic, strong) NSDictionary *font;
|
||||
|
||||
- (void)renderPathTo:(CGContextRef)context;
|
||||
- (void)renderGroupTo:(CGContextRef)context;
|
||||
- (void)renderPathTo:(CGContextRef)context rect:(CGRect)rect;
|
||||
- (void)renderGroupTo:(CGContextRef)context rect:(CGRect)rect;
|
||||
|
||||
- (RNSVGGlyphContext *)getGlyphContext;
|
||||
- (void)pushGlyphContext;
|
||||
|
||||
+41
-33
@@ -23,30 +23,40 @@
|
||||
_font = font;
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
- (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect
|
||||
{
|
||||
[self clip:context];
|
||||
[self setupGlyphContext:context];
|
||||
[self renderGroupTo:context];
|
||||
[self renderGroupTo:context rect:rect];
|
||||
}
|
||||
|
||||
- (void)renderGroupTo:(CGContextRef)context
|
||||
- (void)renderGroupTo:(CGContextRef)context rect:(CGRect)rect
|
||||
{
|
||||
[self pushGlyphContext];
|
||||
|
||||
[self traverseSubviews:^(RNSVGNode *node) {
|
||||
if (node.responsible && !self.svgView.responsible) {
|
||||
self.svgView.responsible = YES;
|
||||
}
|
||||
|
||||
if ([node isKindOfClass:[RNSVGRenderable class]]) {
|
||||
[(RNSVGRenderable*)node mergeProperties:self];
|
||||
}
|
||||
[self traverseSubviews:^(UIView *node) {
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
RNSVGNode* svgNode = (RNSVGNode*)node;
|
||||
if (svgNode.responsible && !self.svgView.responsible) {
|
||||
self.svgView.responsible = YES;
|
||||
}
|
||||
|
||||
[node renderTo:context];
|
||||
if ([node isKindOfClass:[RNSVGRenderable class]]) {
|
||||
[(RNSVGRenderable*)node mergeProperties:self];
|
||||
}
|
||||
|
||||
if ([node isKindOfClass:[RNSVGRenderable class]]) {
|
||||
[(RNSVGRenderable*)node resetProperties];
|
||||
[svgNode renderTo:context rect:rect];
|
||||
|
||||
if ([node isKindOfClass:[RNSVGRenderable class]]) {
|
||||
[(RNSVGRenderable*)node resetProperties];
|
||||
}
|
||||
} else if ([node isKindOfClass:[RNSVGSvgView class]]) {
|
||||
RNSVGSvgView* svgView = (RNSVGSvgView*)node;
|
||||
CGRect rect = CGRectMake(0, 0, [svgView.bbWidth floatValue], [svgView.bbHeight floatValue]);
|
||||
CGContextClipToRect(context, rect);
|
||||
[svgView drawToContext:context withRect:(CGRect)rect];
|
||||
} else {
|
||||
[node drawRect:rect];
|
||||
}
|
||||
|
||||
return YES;
|
||||
@@ -81,42 +91,37 @@
|
||||
[[self.textRoot getGlyphContext] popContext];
|
||||
}
|
||||
|
||||
- (void)renderPathTo:(CGContextRef)context
|
||||
- (void)renderPathTo:(CGContextRef)context rect:(CGRect)rect
|
||||
{
|
||||
[super renderLayerTo:context];
|
||||
[super renderLayerTo:context rect:rect];
|
||||
}
|
||||
|
||||
- (CGPathRef)getPath:(CGContextRef)context
|
||||
{
|
||||
CGMutablePathRef __block path = CGPathCreateMutable();
|
||||
[self traverseSubviews:^(RNSVGNode *node) {
|
||||
CGAffineTransform transform = node.matrix;
|
||||
CGPathAddPath(path, &transform, [node getPath:context]);
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
CGAffineTransform transform = node.matrix;
|
||||
CGPathAddPath(path, &transform, [node getPath:context]);
|
||||
}
|
||||
return YES;
|
||||
}];
|
||||
|
||||
return (CGPathRef)CFAutorelease(path);
|
||||
}
|
||||
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event withTransform:(CGAffineTransform)transform
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||
{
|
||||
UIView *hitSelf = [super hitTest:point withEvent:event withTransform:transform];
|
||||
CGPoint transformed = CGPointApplyAffineTransform(point, self.invmatrix);
|
||||
|
||||
UIView *hitSelf = [super hitTest:transformed withEvent:event];
|
||||
if (hitSelf) {
|
||||
return hitSelf;
|
||||
}
|
||||
|
||||
CGAffineTransform matrix = CGAffineTransformConcat(self.matrix, transform);
|
||||
|
||||
CGPathRef clip = [self getClipPath];
|
||||
if (clip) {
|
||||
CGPathRef transformedClipPath = CGPathCreateCopyByTransformingPath(clip, &matrix);
|
||||
BOOL insideClipPath = CGPathContainsPoint(clip, nil, point, self.clipRule == kRNSVGCGFCRuleEvenodd);
|
||||
CGPathRelease(transformedClipPath);
|
||||
|
||||
if (!insideClipPath) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (clip && !CGPathContainsPoint(clip, nil, transformed, self.clipRule == kRNSVGCGFCRuleEvenodd)) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
for (RNSVGNode *node in [self.subviews reverseObjectEnumerator]) {
|
||||
@@ -130,13 +135,14 @@
|
||||
return node;
|
||||
}
|
||||
|
||||
UIView *hitChild = [node hitTest: point withEvent:event withTransform:matrix];
|
||||
UIView *hitChild = [node hitTest:transformed withEvent:event];
|
||||
|
||||
if (hitChild) {
|
||||
node.active = YES;
|
||||
return (node.responsible || (node != hitChild)) ? hitChild : self;
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@@ -148,7 +154,9 @@
|
||||
}
|
||||
|
||||
[self traverseSubviews:^(__kindof RNSVGNode *node) {
|
||||
[node parseReference];
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
[node parseReference];
|
||||
}
|
||||
return YES;
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
@interface RNSVGSvgView : UIView <RNSVGContainer>
|
||||
|
||||
@property (nonatomic, strong) NSString *bbWidth;
|
||||
@property (nonatomic, strong) NSString *bbHeight;
|
||||
@property (nonatomic, assign) CGFloat minX;
|
||||
@property (nonatomic, assign) CGFloat minY;
|
||||
@property (nonatomic, assign) CGFloat vbWidth;
|
||||
@@ -22,6 +24,8 @@
|
||||
@property (nonatomic, strong) NSString *align;
|
||||
@property (nonatomic, assign) RNSVGVBMOS meetOrSlice;
|
||||
@property (nonatomic, assign) BOOL responsible;
|
||||
@property (nonatomic, assign) CGRect boundingBox;
|
||||
|
||||
|
||||
/**
|
||||
* define <ClipPath></ClipPath> content as clipPath template.
|
||||
@@ -42,4 +46,8 @@
|
||||
|
||||
- (CGRect)getContextBounds;
|
||||
|
||||
- (void)drawRect:(CGRect)rect;
|
||||
|
||||
- (void)drawToContext:(CGContextRef)context withRect:(CGRect)rect;
|
||||
|
||||
@end
|
||||
|
||||
+61
-30
@@ -16,8 +16,8 @@
|
||||
NSMutableDictionary<NSString *, RNSVGNode *> *_clipPaths;
|
||||
NSMutableDictionary<NSString *, RNSVGNode *> *_templates;
|
||||
NSMutableDictionary<NSString *, RNSVGPainter *> *_painters;
|
||||
CGRect _boundingBox;
|
||||
CGAffineTransform _viewBoxTransform;
|
||||
CGAffineTransform _invviewBoxTransform;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
@@ -58,7 +58,7 @@
|
||||
if (minX == _minX) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
[self invalidate];
|
||||
_minX = minX;
|
||||
}
|
||||
@@ -68,7 +68,7 @@
|
||||
if (minY == _minY) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
[self invalidate];
|
||||
_minY = minY;
|
||||
}
|
||||
@@ -78,7 +78,7 @@
|
||||
if (vbWidth == _vbWidth) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
[self invalidate];
|
||||
_vbWidth = vbWidth;
|
||||
}
|
||||
@@ -88,17 +88,37 @@
|
||||
if (_vbHeight == vbHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
[self invalidate];
|
||||
_vbHeight = vbHeight;
|
||||
}
|
||||
|
||||
- (void)setBBWidth:(NSString *)bbWidth
|
||||
{
|
||||
if ([bbWidth isEqualToString:_bbWidth]) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self invalidate];
|
||||
_bbWidth = bbWidth;
|
||||
}
|
||||
|
||||
- (void)setBBHeight:(NSString *)bbHeight
|
||||
{
|
||||
if ([bbHeight isEqualToString:_bbHeight]) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self invalidate];
|
||||
_bbHeight = bbHeight;
|
||||
}
|
||||
|
||||
- (void)setAlign:(NSString *)align
|
||||
{
|
||||
if ([align isEqualToString:_align]) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
[self invalidate];
|
||||
_align = align;
|
||||
}
|
||||
@@ -108,11 +128,32 @@
|
||||
if (meetOrSlice == _meetOrSlice) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
[self invalidate];
|
||||
_meetOrSlice = meetOrSlice;
|
||||
}
|
||||
|
||||
- (void)drawToContext:(CGContextRef)context withRect:(CGRect)rect {
|
||||
|
||||
if (self.align) {
|
||||
_viewBoxTransform = [RNSVGViewBox getTransform:CGRectMake(self.minX, self.minY, self.vbWidth, self.vbHeight)
|
||||
eRect:rect
|
||||
align:self.align
|
||||
meetOrSlice:self.meetOrSlice];
|
||||
_invviewBoxTransform = CGAffineTransformInvert(_viewBoxTransform);
|
||||
CGContextConcatCTM(context, _viewBoxTransform);
|
||||
}
|
||||
|
||||
for (UIView *node in self.subviews) {
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
RNSVGNode *svg = (RNSVGNode *)node;
|
||||
[svg renderTo:context rect:rect];
|
||||
} else {
|
||||
[node drawRect:rect];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)drawRect:(CGRect)rect
|
||||
{
|
||||
_clipPaths = nil;
|
||||
@@ -120,48 +161,38 @@
|
||||
_painters = nil;
|
||||
_boundingBox = rect;
|
||||
CGContextRef context = UIGraphicsGetCurrentContext();
|
||||
|
||||
if (self.align) {
|
||||
_viewBoxTransform = [RNSVGViewBox getTransform:CGRectMake(self.minX, self.minY, self.vbWidth, self.vbHeight)
|
||||
eRect:rect
|
||||
align:self.align
|
||||
meetOrSlice:self.meetOrSlice];
|
||||
CGContextConcatCTM(context, _viewBoxTransform);
|
||||
}
|
||||
|
||||
for (RNSVGNode *node in self.subviews) {
|
||||
|
||||
for (UIView *node in self.subviews) {
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
if (node.responsible && !self.responsible) {
|
||||
RNSVGNode *svg = (RNSVGNode *)node;
|
||||
if (svg.responsible && !self.responsible) {
|
||||
self.responsible = YES;
|
||||
}
|
||||
|
||||
[node parseReference];
|
||||
}
|
||||
}
|
||||
|
||||
for (RNSVGNode *node in self.subviews) {
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
[node renderTo:context];
|
||||
|
||||
[svg parseReference];
|
||||
}
|
||||
}
|
||||
|
||||
[self drawToContext:context withRect:rect];
|
||||
}
|
||||
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||
{
|
||||
if (self.align) {
|
||||
CGPoint transformed = CGPointApplyAffineTransform(point, _invviewBoxTransform);
|
||||
for (RNSVGNode *node in [self.subviews reverseObjectEnumerator]) {
|
||||
if (![node isKindOfClass:[RNSVGNode class]]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (event) {
|
||||
node.active = NO;
|
||||
} else if (node.active) {
|
||||
return node;
|
||||
}
|
||||
|
||||
UIView *hitChild = [node hitTest: point withEvent:event withTransform:_viewBoxTransform];
|
||||
|
||||
|
||||
UIView *hitChild = [node hitTest:transformed withEvent:event];
|
||||
|
||||
if (hitChild) {
|
||||
node.active = YES;
|
||||
return (node.responsible || (node != hitChild)) ? hitChild : self;
|
||||
|
||||
@@ -72,15 +72,15 @@
|
||||
_meetOrSlice = meetOrSlice;
|
||||
}
|
||||
|
||||
- (void)renderTo:(CGContextRef)context
|
||||
- (void)renderTo:(CGContextRef)context rect:(CGRect)rect
|
||||
{
|
||||
// Do not render Symbol
|
||||
}
|
||||
|
||||
- (void)renderSymbolTo:(CGContextRef)context width:(CGFloat)width height:(CGFloat)height
|
||||
{
|
||||
CGRect eRect = CGRectMake(0, 0, width, height);
|
||||
if (self.align) {
|
||||
CGRect eRect = CGRectMake(0, 0, width, height);
|
||||
|
||||
CGAffineTransform viewBoxTransform = [RNSVGViewBox getTransform:CGRectMake(self.minX, self.minY, self.vbWidth, self.vbHeight)
|
||||
eRect:eRect
|
||||
@@ -89,7 +89,7 @@
|
||||
|
||||
CGContextConcatCTM(context, viewBoxTransform);
|
||||
}
|
||||
[self renderGroupTo:context];
|
||||
[self renderGroupTo:context rect:eRect];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
}
|
||||
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
- (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect
|
||||
{
|
||||
RNSVGNode* template = [self.svgView getDefinedTemplate:self.href];
|
||||
if (template) {
|
||||
@@ -37,7 +37,7 @@
|
||||
RNSVGSymbol *symbol = (RNSVGSymbol*)template;
|
||||
[symbol renderSymbolTo:context width:[self relativeOnWidth:self.width] height:[self relativeOnWidth:self.height]];
|
||||
} else {
|
||||
[template renderTo:context];
|
||||
[template renderTo:context rect:rect];
|
||||
}
|
||||
|
||||
if ([template isKindOfClass:[RNSVGRenderable class]]) {
|
||||
|
||||
Reference in New Issue
Block a user