mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-05-28 21:03:51 +00:00
Merge branch 'master' into NativeAnimation
# Conflicts: # android/src/main/java/com/horcrux/svg/RenderableShadowNode.java # android/src/main/java/com/horcrux/svg/SvgViewShadowNode.java # elements/Image.js # elements/Rect.js # elements/Use.js # lib/attributes.js
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
|
||||
- (void)parseReference
|
||||
{
|
||||
[[self getSvgView] defineClipPath:self clipPathName:self.name];
|
||||
[self.svgView defineClipPath:self clipPathName:self.name];
|
||||
}
|
||||
|
||||
|
||||
|
||||
+32
-14
@@ -33,12 +33,14 @@
|
||||
- (void)renderGroupTo:(CGContextRef)context rect:(CGRect)rect
|
||||
{
|
||||
[self pushGlyphContext];
|
||||
RNSVGSvgView* svg = [self getSvgView];
|
||||
|
||||
__block CGRect groupRect = CGRectNull;
|
||||
|
||||
[self traverseSubviews:^(UIView *node) {
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
RNSVGNode* svgNode = (RNSVGNode*)node;
|
||||
if (svgNode.responsible && !svg.responsible) {
|
||||
svg.responsible = YES;
|
||||
if (svgNode.responsible && !self.svgView.responsible) {
|
||||
self.svgView.responsible = YES;
|
||||
}
|
||||
|
||||
if ([node isKindOfClass:[RNSVGRenderable class]]) {
|
||||
@@ -46,6 +48,11 @@
|
||||
}
|
||||
|
||||
[svgNode renderTo:context rect:rect];
|
||||
|
||||
CGRect nodeRect = svgNode.clientRect;
|
||||
if (!CGRectIsEmpty(nodeRect)) {
|
||||
groupRect = CGRectUnion(groupRect, nodeRect);
|
||||
}
|
||||
|
||||
if ([node isKindOfClass:[RNSVGRenderable class]]) {
|
||||
[(RNSVGRenderable*)node resetProperties];
|
||||
@@ -63,6 +70,8 @@
|
||||
|
||||
return YES;
|
||||
}];
|
||||
[self setHitArea:[self getPath:context]];
|
||||
self.clientRect = groupRect;
|
||||
[self popGlyphContext];
|
||||
}
|
||||
|
||||
@@ -84,12 +93,13 @@
|
||||
|
||||
- (void)pushGlyphContext
|
||||
{
|
||||
[[[self getTextRoot] getGlyphContext] pushContext:self font:self.font];
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[[self.textRoot getGlyphContext] pushContext:weakSelf font:self.font];
|
||||
}
|
||||
|
||||
- (void)popGlyphContext
|
||||
{
|
||||
[[[self getTextRoot] getGlyphContext] popContext];
|
||||
[[self.textRoot getGlyphContext] popContext];
|
||||
}
|
||||
|
||||
- (void)renderPathTo:(CGContextRef)context rect:(CGRect)rect
|
||||
@@ -114,16 +124,19 @@
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
|
||||
{
|
||||
CGPoint transformed = CGPointApplyAffineTransform(point, self.invmatrix);
|
||||
|
||||
UIView *hitSelf = [super hitTest:transformed withEvent:event];
|
||||
if (hitSelf) {
|
||||
return hitSelf;
|
||||
}
|
||||
|
||||
|
||||
CGPathRef clip = [self getClipPath];
|
||||
if (clip && !CGPathContainsPoint(clip, nil, transformed, self.clipRule == kRNSVGCGFCRuleEvenodd)) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (!event) {
|
||||
NSPredicate *const anyActive = [NSPredicate predicateWithFormat:@"active == TRUE"];
|
||||
NSArray *const filtered = [self.subviews filteredArrayUsingPredicate:anyActive];
|
||||
if ([filtered count] != 0) {
|
||||
return filtered.firstObject;
|
||||
}
|
||||
}
|
||||
|
||||
for (RNSVGNode *node in [self.subviews reverseObjectEnumerator]) {
|
||||
if (![node isKindOfClass:[RNSVGNode class]]) {
|
||||
@@ -143,15 +156,20 @@
|
||||
return (node.responsible || (node != hitChild)) ? hitChild : self;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
UIView *hitSelf = [super hitTest:transformed withEvent:event];
|
||||
if (hitSelf) {
|
||||
return hitSelf;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)parseReference
|
||||
{
|
||||
if (self.name) {
|
||||
RNSVGSvgView* svg = [self getSvgView];
|
||||
[svg defineTemplate:self templateName:self.name];
|
||||
typeof(self) __weak weakSelf = self;
|
||||
[self.svgView defineTemplate:weakSelf templateName:self.name];
|
||||
}
|
||||
|
||||
[self traverseSubviews:^(__kindof RNSVGNode *node) {
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
#import "RNSVGRenderable.h"
|
||||
#import "RNSVGVBMOS.h"
|
||||
|
||||
@interface RNSVGImage : RNSVGRenderable
|
||||
|
||||
@property (nonatomic, weak) RCTBridge *bridge;
|
||||
@property (nonatomic, assign) id src;
|
||||
@property (nonatomic, strong) NSString* x;
|
||||
@property (nonatomic, strong) NSString* y;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#import "RNSVGImage.h"
|
||||
#import "RCTConvert+RNSVG.h"
|
||||
#import <React/RCTImageSource.h>
|
||||
#import <React/RCTImageLoader.h>
|
||||
#import <React/RCTLog.h>
|
||||
#import "RNSVGViewBox.h"
|
||||
|
||||
@@ -16,6 +17,7 @@
|
||||
{
|
||||
CGImageRef _image;
|
||||
CGSize _imageSize;
|
||||
RCTImageLoaderCancellationBlock _reloadImageCancellationBlock;
|
||||
}
|
||||
|
||||
- (void)setSrc:(id)src
|
||||
@@ -25,14 +27,26 @@
|
||||
}
|
||||
_src = src;
|
||||
CGImageRelease(_image);
|
||||
_image = CGImageRetain([RCTConvert CGImage:src]);
|
||||
RCTImageSource *source = [RCTConvert RCTImageSource:src];
|
||||
if (source.size.width != 0 && source.size.height != 0) {
|
||||
_imageSize = source.size;
|
||||
} else {
|
||||
_imageSize = CGSizeMake(CGImageGetWidth(_image), CGImageGetHeight(_image));
|
||||
_imageSize = CGSizeMake(0, 0);
|
||||
}
|
||||
[self invalidate];
|
||||
|
||||
RCTImageLoaderCancellationBlock previousCancellationBlock = _reloadImageCancellationBlock;
|
||||
if (previousCancellationBlock) {
|
||||
previousCancellationBlock();
|
||||
_reloadImageCancellationBlock = nil;
|
||||
}
|
||||
|
||||
_reloadImageCancellationBlock = [self.bridge.imageLoader loadImageWithURLRequest:[RCTConvert NSURLRequest:src] callback:^(NSError *error, UIImage *image) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
self->_image = CGImageRetain(image.CGImage);
|
||||
self->_imageSize = CGSizeMake(CGImageGetWidth(self->_image), CGImageGetHeight(self->_image));
|
||||
[self invalidate];
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setX:(NSString *)x
|
||||
@@ -94,7 +108,7 @@
|
||||
CGImageRelease(_image);
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
- (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect
|
||||
{
|
||||
CGContextSaveGState(context);
|
||||
|
||||
|
||||
@@ -34,12 +34,11 @@
|
||||
[painter setTransform:self.gradientTransform];
|
||||
[painter setLinearGradientColors:self.gradient];
|
||||
|
||||
RNSVGSvgView *svg = [self getSvgView];
|
||||
if (self.gradientUnits == kRNSVGUnitsUserSpaceOnUse) {
|
||||
[painter setUserSpaceBoundingBox:[svg getContextBounds]];
|
||||
[painter setUserSpaceBoundingBox:[self.svgView getContextBounds]];
|
||||
}
|
||||
|
||||
[svg definePainter:painter painterName:self.name];
|
||||
[self.svgView definePainter:painter painterName:self.name];
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@@ -32,12 +32,11 @@
|
||||
[painter setTransform:self.gradientTransform];
|
||||
[painter setRadialGradientColors:self.gradient];
|
||||
|
||||
RNSVGSvgView *svg = [self getSvgView];
|
||||
if (self.gradientUnits == kRNSVGUnitsUserSpaceOnUse) {
|
||||
[painter setUserSpaceBoundingBox:[svg getContextBounds]];
|
||||
[painter setUserSpaceBoundingBox:[self.svgView getContextBounds]];
|
||||
}
|
||||
|
||||
[svg definePainter:painter painterName:self.name];
|
||||
[self.svgView definePainter:painter painterName:self.name];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -24,7 +24,11 @@
|
||||
@property (nonatomic, strong) NSString *align;
|
||||
@property (nonatomic, assign) RNSVGVBMOS meetOrSlice;
|
||||
@property (nonatomic, assign) BOOL responsible;
|
||||
@property (nonatomic, assign) BOOL active;
|
||||
@property (nonatomic, assign) CGRect boundingBox;
|
||||
@property (nonatomic, assign) CGAffineTransform initialCTM;
|
||||
@property (nonatomic, assign) CGAffineTransform invInitialCTM;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,16 @@
|
||||
CGAffineTransform _invviewBoxTransform;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
{
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
// This is necessary to ensure that [self setNeedsDisplay] actually triggers
|
||||
// a redraw when our parent transitions between hidden and visible.
|
||||
self.contentMode = UIViewContentModeRedraw;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
|
||||
{
|
||||
[super insertReactSubview:subview atIndex:atIndex];
|
||||
@@ -125,6 +135,8 @@
|
||||
|
||||
- (void)drawToContext:(CGContextRef)context withRect:(CGRect)rect {
|
||||
|
||||
self.initialCTM = CGContextGetCTM(context);
|
||||
self.invInitialCTM = CGAffineTransformInvert(self.initialCTM);
|
||||
if (self.align) {
|
||||
_viewBoxTransform = [RNSVGViewBox getTransform:CGRectMake(self.minX, self.minY, self.vbWidth, self.vbHeight)
|
||||
eRect:rect
|
||||
@@ -137,7 +149,8 @@
|
||||
for (UIView *node in self.subviews) {
|
||||
if ([node isKindOfClass:[RNSVGNode class]]) {
|
||||
RNSVGNode *svg = (RNSVGNode *)node;
|
||||
[svg renderTo:context rect:rect];
|
||||
[svg renderTo:context
|
||||
rect:rect];
|
||||
} else {
|
||||
[node drawRect:rect];
|
||||
}
|
||||
|
||||
+18
-1
@@ -24,7 +24,7 @@
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect
|
||||
{
|
||||
RNSVGNode* template = [[self getSvgView] getDefinedTemplate:self.href];
|
||||
RNSVGNode* template = [self.svgView getDefinedTemplate:self.href];
|
||||
if (template) {
|
||||
[self beginTransparencyLayer:context];
|
||||
[self clip:context];
|
||||
@@ -49,6 +49,23 @@
|
||||
// TODO: calling yellow box here
|
||||
RCTLogWarn(@"`Use` element expected a pre-defined svg template as `href` prop, template named: %@ is not defined.", self.href);
|
||||
}
|
||||
self.clientRect = template.clientRect;
|
||||
}
|
||||
|
||||
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
|
||||
const CGPoint transformed = CGPointApplyAffineTransform(point, self.invmatrix);
|
||||
RNSVGNode const* template = [self.svgView getDefinedTemplate:self.href];
|
||||
if (event) {
|
||||
self.active = NO;
|
||||
} else if (self.active) {
|
||||
return self;
|
||||
}
|
||||
UIView const* hitChild = [template hitTest:transformed withEvent:event];
|
||||
if (hitChild) {
|
||||
self.active = YES;
|
||||
return self;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user