Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions android/src/main/java/com/horcrux/svg/GroupView.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@
import android.graphics.Region;
import android.os.Build;
import android.view.View;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.bridge.WritableMap;
import java.util.ArrayList;
import javax.annotation.Nullable;

Expand Down Expand Up @@ -340,4 +342,20 @@ void resetProperties() {
}
}
}

@Override
public void updateShadowNodeMetrics() {
SvgView svgView = this.getSvgView();

if (this.stateWrapper == null || svgView == null) {
return;
}

WritableMap map = Arguments.createMap();
map.putDouble("x", 0);
map.putDouble("y", 0);
map.putDouble("width", svgView.getCanvasWidth() / mScale);
map.putDouble("height", svgView.getCanvasHeight() / mScale);
this.stateWrapper.updateState(map);
}
}
25 changes: 20 additions & 5 deletions android/src/main/java/com/horcrux/svg/RenderableView.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.touch.ReactHitSlopView;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import com.facebook.react.uimanager.PointerEvents;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.regex.Matcher;
Expand Down Expand Up @@ -103,10 +103,8 @@ public abstract class RenderableView extends VirtualView implements ReactHitSlop

public void onReceiveNativeEvent() {
WritableMap event = Arguments.createMap();
ReactContext reactContext = (ReactContext)getContext();
reactContext
.getJSModule(RCTEventEmitter.class)
.receiveEvent(getId(), "topSvgLayout", event);
ReactContext reactContext = (ReactContext) getContext();
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(getId(), "topSvgLayout", event);
}

@Nullable String mFilter;
Expand Down Expand Up @@ -500,6 +498,8 @@ void render(Canvas canvas, Paint paint, float opacity) {
} else {
draw(canvas, paint, opacity);
}

this.updateShadowNodeMetrics();
}

@Override
Expand Down Expand Up @@ -823,4 +823,19 @@ void resetProperties() {
private boolean hasOwnProperty(String propName) {
return mAttributeList != null && mAttributeList.contains(propName);
}

protected void updateShadowNodeMetrics() {
RectF clientRect = this.getClientRect();

if (this.stateWrapper == null || clientRect == null) {
return;
}

WritableMap map = Arguments.createMap();
map.putDouble("x", clientRect.left / mScale);
map.putDouble("y", clientRect.top / mScale);
map.putDouble("width", clientRect.width() / mScale);
map.putDouble("height", clientRect.height() / mScale);
this.stateWrapper.updateState(map);
}
}
11 changes: 11 additions & 0 deletions android/src/main/java/com/horcrux/svg/RenderableViewManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.Dynamic;
import com.facebook.react.bridge.JavaOnlyMap;
import com.facebook.react.bridge.ReadableArray;
Expand All @@ -78,6 +81,8 @@
import com.facebook.react.uimanager.MatrixMathHelper;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.PointerEvents;
import com.facebook.react.uimanager.ReactStylesDiffMap;
import com.facebook.react.uimanager.StateWrapper;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.TransformHelper;
import com.facebook.react.uimanager.ViewGroupManager;
Expand Down Expand Up @@ -166,6 +171,12 @@ protected ViewManagerDelegate getDelegate() {
return mDelegate;
}

@Override
public Object updateState(@NonNull VirtualView view, ReactStylesDiffMap props, StateWrapper stateWrapper) {
view.setStateWrapper(stateWrapper);
return super.updateState(view, props, stateWrapper);
}

static class RenderableShadowNode extends LayoutShadowNode {

@SuppressWarnings({"unused", "EmptyMethod"})
Expand Down
31 changes: 20 additions & 11 deletions android/src/main/java/com/horcrux/svg/VirtualView.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
import com.facebook.react.common.ReactConstants;
import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.PointerEvents;
import com.facebook.react.uimanager.StateWrapper;
import com.facebook.react.uimanager.UIManagerHelper;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.views.view.ReactViewGroup;
import com.horcrux.svg.events.SvgOnLayoutEvent;

import java.util.ArrayList;
import javax.annotation.Nullable;

Expand Down Expand Up @@ -84,6 +84,7 @@ public abstract class VirtualView extends ReactViewGroup {
private float canvasHeight = -1;
private float canvasWidth = -1;
private GlyphContext glyphContext;
protected @Nullable StateWrapper stateWrapper = null;

Path mPath;
Path mFillPath;
Expand All @@ -106,6 +107,10 @@ public void setPointerEvents(PointerEvents pointerEvents) {
mPointerEvents = pointerEvents;
}

public void setStateWrapper(@Nullable StateWrapper stateWrapper) {
this.stateWrapper = stateWrapper;
}

@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
Expand Down Expand Up @@ -249,7 +254,7 @@ int saveAndSetupCanvas(Canvas canvas, Matrix ctm) {
int count = canvas.save();
mCTM.set(mMatrix);
canvas.concat(mCTM);
mCTM.preConcat(ctm);
mCTM.postConcat(ctm);
mCTMInvertible = mCTM.invert(mInvCTM);
return count;
}
Expand Down Expand Up @@ -437,15 +442,19 @@ public SvgView getSvgView() {

double relativeOnWidth(SVGLength length) {
SvgView svg = getSvgView();
if (length.unit == SVGLength.UnitType.PERCENTAGE && svg != null && svg.getViewBox().width() != 0) {
if (length.unit == SVGLength.UnitType.PERCENTAGE
&& svg != null
&& svg.getViewBox().width() != 0) {
return relativeOn(length, svg.getViewBox().width());
}
return relativeOn(length, getCanvasWidth());
}

double relativeOnHeight(SVGLength length) {
SvgView svg = getSvgView();
if (length.unit == SVGLength.UnitType.PERCENTAGE && svg != null && svg.getViewBox().height() != 0) {
if (length.unit == SVGLength.UnitType.PERCENTAGE
&& svg != null
&& svg.getViewBox().height() != 0) {
return relativeOn(length, svg.getViewBox().height());
}
return relativeOn(length, getCanvasHeight());
Expand Down Expand Up @@ -612,13 +621,13 @@ void setClientRect(RectF rect) {
UIManagerHelper.getEventDispatcherForReactTag(mContext, getId());
if (eventDispatcher != null) {
eventDispatcher.dispatchEvent(
new SvgOnLayoutEvent(
UIManagerHelper.getSurfaceId(VirtualView.this),
this.getId(),
left,
top,
width,
height));
new SvgOnLayoutEvent(
UIManagerHelper.getSurfaceId(VirtualView.this),
this.getId(),
left,
top,
width,
height));
}
}

Expand Down
11 changes: 11 additions & 0 deletions apple/Elements/RNSVGGroup.mm
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#import "RNSVGRenderUtils.h"
#endif // RCT_NEW_ARCH_ENABLED

@implementation RNSVGGroup {
Expand Down Expand Up @@ -308,6 +309,16 @@ - (void)resetProperties
}];
}

#ifdef RCT_NEW_ARCH_ENABLED
- (void)updateShadowNodeMetrics
{
auto statePtr = [self state];
if (statePtr) {
statePtr->updateState(RNSVGLayoutableState(0, 0, [self getCanvasWidth], [self getCanvasHeight]));
}
}
#endif

@end

#ifdef RCT_NEW_ARCH_ENABLED
Expand Down
14 changes: 14 additions & 0 deletions apple/RNSVGRenderable.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
#import "RNSVGNode.h"
#import "RNSVGVectorEffect.h"

#ifdef RCT_NEW_ARCH_ENABLED
#import <rnsvg/RNSVGComponentDescriptors.h>

using namespace facebook::react;
#endif

@interface RNSVGRenderable : RNSVGNode

@property (class) RNSVGRenderable *contextElement;
Expand All @@ -36,6 +42,10 @@
@property (nonatomic, assign) CGPathRef hitArea;
@property (nonatomic, strong) NSString *filter;

#ifdef RCT_NEW_ARCH_ENABLED
- (facebook::react::RNSVGRenderableShadowNode::ConcreteState::Shared)state;
#endif

- (void)setColor:(RNSVGColor *)color;

- (void)setHitArea:(CGPathRef)path;
Expand All @@ -48,4 +58,8 @@

- (CGColor *)getCurrentColor;

#ifdef RCT_NEW_ARCH_ENABLED
- (void)updateShadowNodeMetrics;
#endif

@end
25 changes: 25 additions & 0 deletions apple/RNSVGRenderable.mm
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ @implementation RNSVGRenderable {
CGFloat *_strokeDashArrayData;
CGPathRef _srcHitPath;
RNSVGRenderable *_caller;

#ifdef RCT_NEW_ARCH_ENABLED
RNSVGRenderableShadowNode::ConcreteState::Shared _state;
#endif
}

static RNSVGRenderable *_contextElement;
Expand Down Expand Up @@ -243,6 +247,11 @@ - (void)prepareForRecycle
_filter = nil;
_caller = nil;
}

- (void)updateState:(State::Shared const &)state oldState:(State::Shared const &)oldState
{
_state = std::static_pointer_cast<const RNSVGRenderableShadowNode::ConcreteState>(state);
}
#endif // RCT_NEW_ARCH_ENABLED

UInt32 saturate(CGFloat value)
Expand Down Expand Up @@ -432,6 +441,9 @@ - (void)renderTo:(CGContextRef)context rect:(CGRect)rect
CGContextRestoreGState(context);

[self renderMarkers:context path:self.path rect:&rect];
#ifdef RCT_NEW_ARCH_ENABLED
[self updateShadowNodeMetrics];
#endif
}

- (void)prepareStrokeDash:(NSUInteger)count strokeDasharray:(NSArray<RNSVGLength *> *)strokeDasharray
Expand Down Expand Up @@ -773,4 +785,17 @@ - (CGColor *)getCurrentColor
return nil;
}

#ifdef RCT_NEW_ARCH_ENABLED
- (void)updateShadowNodeMetrics
{
if (_state) {
_state->updateState(RNSVGLayoutableState(self.clientRect.origin.x, self.clientRect.origin.y, self.clientRect.size.width, self.clientRect.size.height));
}
}

- (RNSVGRenderableShadowNode::ConcreteState::Shared)state {
return _state;
}
#endif

@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// RNSVGComponentDescriptor.h
#pragma once
#include <react/debug/react_native_assert.h>
#include <react/renderer/core/ConcreteComponentDescriptor.h>
#include "RNSVGShadowNodes.h"

namespace facebook::react {

template <typename ShadowNodeT>
class RNSVGComponentDescriptor final
: public ConcreteComponentDescriptor<ShadowNodeT> {
public:
using ConcreteComponentDescriptor<ShadowNodeT>::ConcreteComponentDescriptor;
void adopt(ShadowNode &shadowNode) const override {
react_native_assert(dynamic_cast<RNSVGLayoutableShadowNode *>(&shadowNode));
auto layoutableShadowNode = dynamic_cast<RNSVGLayoutableShadowNode *>(&shadowNode);

auto state = std::static_pointer_cast<const typename ShadowNodeT::ConcreteState>(shadowNode.getState());
auto stateData = state->getData();

if (stateData.getWidth() != 0 && stateData.getHeight() != 0) {
layoutableShadowNode->setSize(Size{stateData.getWidth(), stateData.getHeight()});
layoutableShadowNode->setShadowNodePosition(stateData.getX(), stateData.getY());
}

ConcreteComponentDescriptor<ShadowNodeT>::adopt(shadowNode);
}
};

} // namespace facebook::react
Loading
Loading