124 lines
3.1 KiB
Objective-C
124 lines
3.1 KiB
Objective-C
/**
|
|
* 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 "RNSVGGroup.h"
|
|
|
|
@implementation RNSVGGroup
|
|
|
|
- (void)renderLayerTo:(CGContextRef)context
|
|
{
|
|
[self clip:context];
|
|
[self renderGroupTo:context];
|
|
}
|
|
|
|
- (void)renderGroupTo:(CGContextRef)context
|
|
{
|
|
RNSVGSvgView* svg = [self getSvgView];
|
|
[self traverseSubviews:^(RNSVGNode *node) {
|
|
if (node.responsible && !svg.responsible) {
|
|
svg.responsible = YES;
|
|
}
|
|
|
|
if ([node isKindOfClass:[RNSVGRenderable class]]) {
|
|
[(RNSVGRenderable*)node mergeProperties:self];
|
|
}
|
|
|
|
[node renderTo:context];
|
|
|
|
if ([node isKindOfClass:[RNSVGRenderable class]]) {
|
|
[(RNSVGRenderable*)node resetProperties];
|
|
}
|
|
|
|
return YES;
|
|
}];
|
|
}
|
|
|
|
- (void)renderPathTo:(CGContextRef)context
|
|
{
|
|
[super renderLayerTo:context];
|
|
}
|
|
|
|
- (CGPathRef)getPath:(CGContextRef)context
|
|
{
|
|
CGMutablePathRef __block path = CGPathCreateMutable();
|
|
[self traverseSubviews:^(RNSVGNode *node) {
|
|
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 *hitSelf = [super hitTest:point withEvent:event withTransform:transform];
|
|
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;
|
|
}
|
|
|
|
}
|
|
|
|
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:matrix];
|
|
|
|
if (hitChild) {
|
|
node.active = YES;
|
|
return (node.responsible || (node != hitChild)) ? hitChild : self;
|
|
}
|
|
}
|
|
return nil;
|
|
}
|
|
|
|
- (void)parseReference
|
|
{
|
|
if (self.name) {
|
|
RNSVGSvgView* svg = [self getSvgView];
|
|
[svg defineTemplate:self templateName:self.name];
|
|
}
|
|
|
|
[self traverseSubviews:^(__kindof RNSVGNode *node) {
|
|
[node parseReference];
|
|
return YES;
|
|
}];
|
|
}
|
|
|
|
- (void)resetProperties
|
|
{
|
|
[self traverseSubviews:^(__kindof RNSVGNode *node) {
|
|
if ([node isKindOfClass:[RNSVGRenderable class]]) {
|
|
[(RNSVGRenderable*)node resetProperties];
|
|
}
|
|
return YES;
|
|
}];
|
|
}
|
|
|
|
@end
|