diff --git a/android/src/main/java/com/horcrux/svg/RenderableView.java b/android/src/main/java/com/horcrux/svg/RenderableView.java index cb5750e75..a0b19ea9a 100644 --- a/android/src/main/java/com/horcrux/svg/RenderableView.java +++ b/android/src/main/java/com/horcrux/svg/RenderableView.java @@ -96,6 +96,7 @@ public abstract class RenderableView extends VirtualView implements ReactHitSlop private @Nullable ArrayList mOriginProperties; private @Nullable ArrayList mPropList; private @Nullable ArrayList mAttributeList; + private @Nullable RenderableView mCaller; @Nullable String mFilter; @@ -134,6 +135,9 @@ int getCurrentColor() { if (this.mCurrentColor != 0) { return this.mCurrentColor; } + if (this.mCaller != null) { + return this.mCaller.getCurrentColor(); + } ViewParent parent = this.getParent(); if (parent instanceof VirtualView) { return ((RenderableView) parent).getCurrentColor(); @@ -756,6 +760,7 @@ private ArrayList getAttributeList() { } void mergeProperties(RenderableView target) { + mCaller = target; ArrayList targetAttributeList = target.getAttributeList(); if (targetAttributeList == null || targetAttributeList.size() == 0) { @@ -798,6 +803,7 @@ void resetProperties() { mLastMergedList = null; mOriginProperties = null; mAttributeList = mPropList; + mCaller = null; } } diff --git a/android/src/main/java/com/horcrux/svg/SvgView.java b/android/src/main/java/com/horcrux/svg/SvgView.java index 346873cca..f00d54c18 100644 --- a/android/src/main/java/com/horcrux/svg/SvgView.java +++ b/android/src/main/java/com/horcrux/svg/SvgView.java @@ -11,6 +11,7 @@ import android.annotation.SuppressLint; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Rect; @@ -189,7 +190,7 @@ public int reactTagForTouch(float touchX, float touchY) { final Matrix mInvViewBoxMatrix = new Matrix(); private boolean mInvertible = true; private boolean mRendered = false; - int mCurrentColor = 0; + int mCurrentColor = Color.BLACK; boolean notRendered() { return !mRendered; diff --git a/apple/Brushes/RNSVGContextBrush.mm b/apple/Brushes/RNSVGContextBrush.mm index 874fe391a..daa92f699 100644 --- a/apple/Brushes/RNSVGContextBrush.mm +++ b/apple/Brushes/RNSVGContextBrush.mm @@ -49,7 +49,7 @@ - (BOOL)applyFillColor:(CGContextRef)context opacity:(CGFloat)opacity BOOL fillColor; if (brush.class == RNSVGBrush.class) { - CGContextSetFillColorWithColor(context, [element.tintColor CGColor]); + CGContextSetFillColorWithColor(context, [element getCurrentColor]); fillColor = YES; } else { fillColor = [brush applyFillColor:context opacity:opacity]; @@ -70,7 +70,7 @@ - (BOOL)applyStrokeColor:(CGContextRef)context opacity:(CGFloat)opacity BOOL strokeColor; if (brush.class == RNSVGBrush.class) { - CGContextSetStrokeColorWithColor(context, [element.tintColor CGColor]); + CGContextSetStrokeColorWithColor(context, [element getCurrentColor]); strokeColor = YES; } else { strokeColor = [brush applyStrokeColor:context opacity:opacity]; diff --git a/apple/Elements/RNSVGSvgView.h b/apple/Elements/RNSVGSvgView.h index c75ddfc66..992ad9405 100644 --- a/apple/Elements/RNSVGSvgView.h +++ b/apple/Elements/RNSVGSvgView.h @@ -19,6 +19,7 @@ @interface RNSVGSvgView : RNSVGView +@property (nonatomic, strong) RNSVGColor *color; @property (nonatomic, strong) RNSVGLength *bbWidth; @property (nonatomic, strong) RNSVGLength *bbHeight; @property (nonatomic, assign) CGFloat minX; diff --git a/apple/Elements/RNSVGSvgView.mm b/apple/Elements/RNSVGSvgView.mm index 644a754db..97b4b7269 100644 --- a/apple/Elements/RNSVGSvgView.mm +++ b/apple/Elements/RNSVGSvgView.mm @@ -47,8 +47,6 @@ - (instancetype)initWithFrame:(CGRect)frame // This is necessary to ensure that [self setNeedsDisplay] actually triggers // a redraw when our parent transitions between hidden and visible. self.contentMode = UIViewContentModeRedraw; - // We don't want the dimming effect on tint as it's used as currentColor - self.tintAdjustmentMode = UIViewTintAdjustmentModeNormal; #endif // TARGET_OS_OSX rendered = false; #ifdef RCT_NEW_ARCH_ENABLED @@ -90,7 +88,7 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const & self.align = RCTNSStringFromStringNilIfEmpty(newProps.align); self.meetOrSlice = intToRNSVGVBMOS(newProps.meetOrSlice); if (RCTUIColorFromSharedColor(newProps.color)) { - self.tintColor = RCTUIColorFromSharedColor(newProps.color); + self.color = RCTUIColorFromSharedColor(newProps.color); } [super updateProps:props oldProps:oldProps]; } @@ -184,10 +182,13 @@ - (void)invalidate [self setNeedsDisplay]; } -- (void)tintColorDidChange +- (void)setColor:(RNSVGColor *)color { + if (color == _color) { + return; + } [self invalidate]; - [self clearChildCache]; + _color = color; } - (void)setMinX:(CGFloat)minX diff --git a/apple/RNSVGRenderable.h b/apple/RNSVGRenderable.h index 82a964a10..7f56488d9 100644 --- a/apple/RNSVGRenderable.h +++ b/apple/RNSVGRenderable.h @@ -19,6 +19,7 @@ @interface RNSVGRenderable : RNSVGNode @property (class) RNSVGRenderable *contextElement; +@property (nonatomic, strong) RNSVGColor *color; @property (nonatomic, strong) RNSVGBrush *fill; @property (nonatomic, assign) CGFloat fillOpacity; @property (nonatomic, assign) RNSVGCGFCRule fillRule; @@ -45,4 +46,6 @@ - (void)resetProperties; +- (CGColor *)getCurrentColor; + @end diff --git a/apple/RNSVGRenderable.mm b/apple/RNSVGRenderable.mm index f9d633ec9..0cc82c095 100644 --- a/apple/RNSVGRenderable.mm +++ b/apple/RNSVGRenderable.mm @@ -25,6 +25,7 @@ @implementation RNSVGRenderable { NSArray *_sourceStrokeDashArray; CGFloat *_strokeDashArrayData; CGPathRef _srcHitPath; + RNSVGRenderable *_caller; } static RNSVGRenderable *_contextElement; @@ -61,11 +62,11 @@ - (void)invalidate - (void)setColor:(RNSVGColor *)color { - if (color == self.tintColor) { + if (color == _color) { return; } [self invalidate]; - self.tintColor = color; + _color = color; } - (void)setFill:(RNSVGBrush *)fill @@ -560,7 +561,7 @@ - (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect if (self.fill) { if (self.fill.class == RNSVGBrush.class) { - CGContextSetFillColorWithColor(context, [self.tintColor CGColor]); + CGContextSetFillColorWithColor(context, [self getCurrentColor]); fillColor = YES; } else { fillColor = [self.fill applyFillColor:context opacity:self.fillOpacity]; @@ -608,7 +609,7 @@ - (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect BOOL strokeColor; if (self.stroke.class == RNSVGBrush.class) { - CGContextSetStrokeColorWithColor(context, [self.tintColor CGColor]); + CGContextSetStrokeColorWithColor(context, [self getCurrentColor]); strokeColor = YES; } else { strokeColor = [self.stroke applyStrokeColor:context opacity:self.strokeOpacity]; @@ -724,6 +725,7 @@ - (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event - (void)mergeProperties:(__kindof RNSVGRenderable *)target { + _caller = target; NSArray *targetAttributeList = [target getAttributeList]; if (targetAttributeList.count == 0) { @@ -754,9 +756,28 @@ - (void)resetProperties [self setValue:[_originProperties valueForKey:key] forKey:key]; } + _caller = nil; _lastMergedList = nil; _attributeList = _propList; self.merging = false; } +- (CGColor *)getCurrentColor +{ + if (self.color != nil) { + return [self.color CGColor]; + } + if (_caller != nil) { + return [_caller getCurrentColor]; + } + RNSVGPlatformView *parentView = [self superview]; + if ([parentView isKindOfClass:[RNSVGRenderable class]]) { + return [(RNSVGRenderable *)parentView getCurrentColor]; + } else if ([parentView isKindOfClass:[RNSVGSvgView class]]) { + return [[(RNSVGSvgView *)parentView color] CGColor]; + } + + return nil; +} + @end diff --git a/apple/RNSVGUIKit.macos.mm b/apple/RNSVGUIKit.macos.mm index c4484ff11..9e1caed80 100644 --- a/apple/RNSVGUIKit.macos.mm +++ b/apple/RNSVGUIKit.macos.mm @@ -1,7 +1,6 @@ #import "RNSVGUIKit.h" @implementation RNSVGView { - NSColor *_tintColor; } - (CGPoint)center @@ -20,29 +19,6 @@ - (void)setCenter:(CGPoint)point self.frame = CGRectMake(xOrigin, yOrigin, frameRect.size.width, frameRect.size.height); } -- (NSColor *)tintColor -{ - if (_tintColor != nil) { - return _tintColor; - } - - // To mimic iOS's tintColor, we crawl up the view hierarchy until either: - // (a) we find a valid color - // (b) we reach a view that isn't an RNSVGView - NSView *parentView = [self superview]; - if ([parentView isKindOfClass:[RNSVGView class]]) { - return [(RNSVGView *)parentView tintColor]; - } else { - return [NSColor controlAccentColor]; - } -} - -- (void)setTintColor:(NSColor *)tintColor -{ - _tintColor = tintColor; - [self setNeedsDisplay:YES]; -} - @end @implementation NSImage (RNSVGMacOSExtensions) diff --git a/apple/Text/RNSVGTSpan.mm b/apple/Text/RNSVGTSpan.mm index 7e00778f4..5f3039eb2 100644 --- a/apple/Text/RNSVGTSpan.mm +++ b/apple/Text/RNSVGTSpan.mm @@ -133,7 +133,7 @@ - (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect if (self.inlineSize != nil && self.inlineSize.value != 0) { if (self.fill) { if (self.fill.class == RNSVGBrush.class) { - CGColorRef color = [self.tintColor CGColor]; + CGColorRef color = [self getCurrentColor]; [self drawWrappedText:context gc:gc rect:rect color:color]; } else { CGColorRef color = [self.fill getColorWithOpacity:self.fillOpacity]; @@ -143,7 +143,7 @@ - (void)renderLayerTo:(CGContextRef)context rect:(CGRect)rect } if (self.stroke) { if (self.stroke.class == RNSVGBrush.class) { - CGColorRef color = [self.tintColor CGColor]; + CGColorRef color = [self getCurrentColor]; [self drawWrappedText:context gc:gc rect:rect color:color]; } else { CGColorRef color = [self.stroke getColorWithOpacity:self.strokeOpacity]; diff --git a/apple/ViewManagers/RNSVGRenderableManager.mm b/apple/ViewManagers/RNSVGRenderableManager.mm index 612de16e3..7beca344f 100644 --- a/apple/ViewManagers/RNSVGRenderableManager.mm +++ b/apple/ViewManagers/RNSVGRenderableManager.mm @@ -24,7 +24,7 @@ - (RNSVGRenderable *)node return [RNSVGRenderable new]; } -RCT_REMAP_VIEW_PROPERTY(color, tintColor, UIColor) +RCT_EXPORT_VIEW_PROPERTY(color, UIColor) RCT_EXPORT_VIEW_PROPERTY(fill, RNSVGBrush) RCT_EXPORT_VIEW_PROPERTY(fillOpacity, CGFloat) RCT_EXPORT_VIEW_PROPERTY(fillRule, RNSVGCGFCRule) diff --git a/apple/ViewManagers/RNSVGSvgViewManager.mm b/apple/ViewManagers/RNSVGSvgViewManager.mm index a9e5bee57..73ebd2407 100644 --- a/apple/ViewManagers/RNSVGSvgViewManager.mm +++ b/apple/ViewManagers/RNSVGSvgViewManager.mm @@ -26,7 +26,7 @@ - (RNSVGPlatformView *)view RCT_EXPORT_VIEW_PROPERTY(vbHeight, CGFloat) RCT_EXPORT_VIEW_PROPERTY(align, NSString) RCT_EXPORT_VIEW_PROPERTY(meetOrSlice, RNSVGVBMOS) -RCT_REMAP_VIEW_PROPERTY(color, tintColor, UIColor) +RCT_EXPORT_VIEW_PROPERTY(color, UIColor) RCT_CUSTOM_VIEW_PROPERTY(hitSlop, UIEdgeInsets, RNSVGSvgView) { if ([view respondsToSelector:@selector(setHitTestEdgeInsets:)]) { diff --git a/apps/common/test/Test2520.tsx b/apps/common/test/Test2520.tsx new file mode 100644 index 000000000..97791c5b6 --- /dev/null +++ b/apps/common/test/Test2520.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import {View} from 'react-native'; +import {Defs, G, Rect, Svg, Use} from 'react-native-svg'; + +export default () => { + return ( + + + {/* @ts-ignore */} + + + + + + + + + + + + + + + ); +}; diff --git a/apps/common/test/index.tsx b/apps/common/test/index.tsx index 131e6befb..251336f76 100644 --- a/apps/common/test/index.tsx +++ b/apps/common/test/index.tsx @@ -34,6 +34,7 @@ import Test2407 from './Test2407'; import Test2417 from './Test2417'; import Test2455 from './Test2455'; import Test2471 from './Test2471'; +import Test2520 from './Test2520'; export default function App() { return ; diff --git a/src/elements/Svg.tsx b/src/elements/Svg.tsx index 36edd2cec..1656c3577 100644 --- a/src/elements/Svg.tsx +++ b/src/elements/Svg.tsx @@ -107,7 +107,6 @@ export default class Svg extends Shape { ...extracted, }; let { - color, width, height, focusable, @@ -173,8 +172,6 @@ export default class Svg extends Shape { extractResponder(props, props, this as ResponderInstanceProps); - props.tintColor = color; - if (onLayout != null) { props.onLayout = onLayout; }