Skip to content

Implement intrinsic size based on viewBox (height / width auto) #1720

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
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
2 changes: 1 addition & 1 deletion android/src/main/java/com/horcrux/svg/SVGLength.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ private SVGLength() {
length = length.trim();
int stringLength = length.length();
int percentIndex = stringLength - 1;
if (stringLength == 0 || length.equals("normal")) {
if (stringLength == 0 || length.equals("normal") || length.equals("auto")) {
unit = UnitType.UNKNOWN;
value = 0;
} else if (length.codePointAt(percentIndex) == '%') {
Expand Down
60 changes: 60 additions & 0 deletions android/src/main/java/com/horcrux/svg/SvgShadowNode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* 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.
*/

package com.horcrux.svg;

import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.views.text.ReactBaseTextShadowNode;
import com.facebook.yoga.YogaMeasureFunction;
import com.facebook.yoga.YogaMeasureMode;
import com.facebook.yoga.YogaMeasureOutput;
import com.facebook.yoga.YogaNode;

public class SvgShadowNode extends ReactBaseTextShadowNode implements YogaMeasureFunction {
private float mVbWidth = 0;
private float mVbHeight = 0;

public SvgShadowNode() {
setMeasureFunction(this);
}

@ReactProp(name = "vbWidth")
public void setVbWidth(float vbWidth) {
mVbWidth = vbWidth;
}

@ReactProp(name = "vbHeight")
public void setVbHeight(float vbHeight) {
mVbHeight = vbHeight;
}

@Override
public long measure(
YogaNode node,
float baseWidth,
YogaMeasureMode widthMode,
float baseHeight,
YogaMeasureMode heightMode) {

float width = baseWidth;
float height = baseHeight;
float maxWidth = widthMode == YogaMeasureMode.AT_MOST ? width : Float.MAX_VALUE;
float maxHeight = heightMode == YogaMeasureMode.AT_MOST ? height : Float.MAX_VALUE;

if (mVbWidth != 0 && mVbHeight != 0) {
if (widthMode != YogaMeasureMode.EXACTLY) {
width = Math.min(mVbWidth / mVbHeight * height, maxWidth);
}
if (heightMode != YogaMeasureMode.EXACTLY) {
height = Math.min(mVbHeight / mVbWidth * width, maxHeight);
}
}

return YogaMeasureOutput.make(width, height);
}
}
5 changes: 5 additions & 0 deletions android/src/main/java/com/horcrux/svg/SvgViewManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ public ReactViewGroup createViewInstance(ThemedReactContext reactContext) {
return new SvgView(reactContext);
}

@Override
public SvgShadowNode createShadowNodeInstance() {
return new SvgShadowNode();
}

@Override
public void updateExtraData(ReactViewGroup root, Object extraData) {
super.updateExtraData(root, extraData);
Expand Down
4 changes: 3 additions & 1 deletion android/src/main/jni/rnsvg.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <ReactCommon/JavaTurboModule.h>
#include <ReactCommon/TurboModule.h>
#include <jsi/jsi.h>
#include <react/renderer/components/rnsvg/RNSVGComponentDescriptors.h>
#include <react/renderer/components/rnsvg/RNSVGSvgViewAndroidComponentDescriptor.h>
#include <react/renderer/components/rnsvg/RNSVGImageComponentDescriptor.h>

namespace facebook {
Expand All @@ -29,4 +31,4 @@ JSI_EXPORT
std::shared_ptr<TurboModule> rnsvg_ModuleProvider(const std::string &moduleName, const JavaTurboModule::InitParams &params);

} // namespace react
} // namespace facebook
} // namespace facebook
2 changes: 1 addition & 1 deletion apple/Elements/RNSVGClipPath.mm
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
2 changes: 1 addition & 1 deletion apple/Elements/RNSVGDefs.mm
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
2 changes: 1 addition & 1 deletion apple/Elements/RNSVGForeignObject.mm
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
2 changes: 1 addition & 1 deletion apple/Elements/RNSVGGroup.mm
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
2 changes: 1 addition & 1 deletion apple/Elements/RNSVGLinearGradient.mm
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
2 changes: 1 addition & 1 deletion apple/Elements/RNSVGMarker.mm
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
2 changes: 1 addition & 1 deletion apple/Elements/RNSVGMask.mm
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
2 changes: 1 addition & 1 deletion apple/Elements/RNSVGPath.mm
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
2 changes: 1 addition & 1 deletion apple/Elements/RNSVGPattern.mm
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
2 changes: 1 addition & 1 deletion apple/Elements/RNSVGRadialGradient.mm
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
3 changes: 2 additions & 1 deletion apple/Elements/RNSVGSvgView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import <rnsvg/RNSVGSvgViewComponentDescriptor.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
2 changes: 1 addition & 1 deletion apple/Elements/RNSVGSymbol.mm
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
2 changes: 1 addition & 1 deletion apple/Elements/RNSVGUse.mm
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
2 changes: 1 addition & 1 deletion apple/Shapes/RNSVGCircle.mm
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
2 changes: 1 addition & 1 deletion apple/Shapes/RNSVGEllipse.mm
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
2 changes: 1 addition & 1 deletion apple/Shapes/RNSVGLine.mm
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
2 changes: 1 addition & 1 deletion apple/Shapes/RNSVGRect.mm
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
2 changes: 1 addition & 1 deletion apple/Text/RNSVGTSpan.mm
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
2 changes: 1 addition & 1 deletion apple/Text/RNSVGText.mm
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
2 changes: 1 addition & 1 deletion apple/Text/RNSVGTextPath.mm
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
#ifdef RCT_NEW_ARCH_ENABLED
#import <React/RCTConversions.h>
#import <React/RCTFabricComponentsPlugins.h>
#import <react/renderer/components/rnsvg/ComponentDescriptors.h>
#import <react/renderer/components/view/conversions.h>
#import <rnsvg/RNSVGComponentDescriptors.h>
#import "RNSVGFabricConversions.h"
#endif // RCT_NEW_ARCH_ENABLED

Expand Down
27 changes: 27 additions & 0 deletions apple/ViewManagers/RNSVGSvgShadowView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* 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.
*/

#if !TARGET_OS_OSX // ![macOS]
#import <UIKit/UIKit.h>
#else // [macOS]
#import <React/RCTUIKit.h> // [macOS]
#endif
#import <React/RCTShadowView.h>

@class RCTBridge;

NS_ASSUME_NONNULL_BEGIN

@interface RNSVGSvgShadowView : RCTShadowView

@property (nonatomic, assign) CGFloat vbWidth;
@property (nonatomic, assign) CGFloat vbHeight;

@end

NS_ASSUME_NONNULL_END
61 changes: 61 additions & 0 deletions apple/ViewManagers/RNSVGSvgShadowView.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* 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 "RNSVGSvgShadowView.h"

@implementation RNSVGSvgShadowView

- (instancetype)init
{
if (self = [super init]) {
YGNodeSetMeasureFunc(self.yogaNode, RNSVGSvgShadowViewMeasure);
}

return self;
}

static YGSize RNSVGSvgShadowViewMeasure(
const struct YGNode *node,
float width,
YGMeasureMode widthMode,
float height,
YGMeasureMode heightMode)
{
RNSVGSvgShadowView *shadowView = (__bridge RNSVGSvgShadowView *)YGNodeGetContext(node);

CGSize size = {width, height};
CGSize maximumSize = {
widthMode == YGMeasureModeAtMost ? size.width : CGFLOAT_MAX,
heightMode == YGMeasureModeAtMost ? size.height : CGFLOAT_MAX,
};
if (shadowView.vbWidth != 0 && shadowView.vbHeight != 0) {
if (widthMode != YGMeasureModeExactly) {
size.width = MIN(shadowView.vbWidth / shadowView.vbHeight * size.height, maximumSize.width);
}
if (heightMode != YGMeasureModeExactly) {
size.height = MIN(shadowView.vbHeight / shadowView.vbWidth * size.width, maximumSize.height);
}
}

return (YGSize){
RCTYogaFloatFromCoreGraphicsFloat(size.width),
RCTYogaFloatFromCoreGraphicsFloat(size.height),
};
}

- (BOOL)isYogaLeafNode
{
return YES;
}

- (void)layoutSubviewsWithContext:(RCTLayoutContext)layoutContext
{
// Do nothing.
}

@end
Loading
Loading