Merge pull request #1494 from amgleitman/amgleitman/macos

Add macOS support
This commit is contained in:
Adam Gleitman
2021-03-29 18:07:33 -07:00
committed by GitHub
140 changed files with 336 additions and 116 deletions
+1 -1
View File
@@ -4,5 +4,5 @@ Example/android/
Example/ios/
screenshots/
android/
ios/
apple/
src/lib/extract/transform.js
+13 -11
View File
@@ -3,15 +3,17 @@ require 'json'
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
Pod::Spec.new do |s|
s.name = 'RNSVG'
s.version = package['version']
s.summary = package['description']
s.license = package['license']
s.homepage = package['homepage']
s.authors = 'Horcrux Chen'
s.platforms = { :ios => "9.0", :tvos => "9.2" }
s.source = { :git => 'https://github.com/react-native-community/react-native-svg.git', :tag => "v#{s.version}" }
s.source_files = 'ios/**/*.{h,m}'
s.requires_arc = true
s.dependency 'React'
s.name = 'RNSVG'
s.version = package['version']
s.summary = package['description']
s.license = package['license']
s.homepage = package['homepage']
s.authors = 'Horcrux Chen'
s.platforms = { :osx => "10.14", :ios => "9.0", :tvos => "9.2" }
s.source = { :git => 'https://github.com/react-native-community/react-native-svg.git', :tag => "v#{s.version}" }
s.source_files = 'apple/**/*.{h,m}'
s.ios.exclude_files = '**/*.macos.{h,m}'
s.osx.exclude_files = '**/*.ios.{h,m}'
s.requires_arc = true
s.dependency 'React'
end
View File
@@ -159,6 +159,11 @@ void PatternFunction(void* info, CGContextRef context)
CGFloat h = [self getVal:[_points objectAtIndex:3] relative:height];
CGAffineTransform viewbox = [self.pattern.svgView getViewBoxTransform];
#if TARGET_OS_OSX
// This is needed because macOS and iOS have different conventions for where the origin is.
// For macOS, it's in the bottom-left corner. For iOS, it's in the top-left corner.
viewbox = CGAffineTransformScale(viewbox, 1, -1);
#endif
CGRect newBounds = CGRectMake(x, y, w, h);
CGSize size = newBounds.size;
self.useObjectBoundingBoxForContentUnits = _useContentObjectBoundingBox;
@@ -19,9 +19,9 @@
- (BOOL)isSimpleClipPath
{
NSArray<UIView*> *children = self.subviews;
NSArray<RNSVGView*> *children = self.subviews;
if (children.count == 1) {
UIView* child = children[0];
RNSVGView* child = children[0];
if ([child class] != [RNSVGGroup class]) {
return true;
}
@@ -9,7 +9,7 @@
#import "RNSVGNode.h"
/**
* RNSVG defination are implemented as abstract UIViews for all elements inside Defs.
* RNSVG defination are implemented as abstract views for all elements inside Defs.
*/
@interface RNSVGDefs : RNSVGNode
@@ -27,7 +27,7 @@
}];
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
- (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
return nil;
}
@@ -12,7 +12,7 @@
@implementation RNSVGForeignObject
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
- (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
return nil;
}
@@ -42,7 +42,7 @@
__block CGRect bounds = CGRectNull;
[self traverseSubviews:^(UIView *node) {
[self traverseSubviews:^(RNSVGView *node) {
if ([node isKindOfClass:[RNSVGMask class]] || [node isKindOfClass:[RNSVGClipPath class]]) {
// no-op
} else if ([node isKindOfClass:[RNSVGNode class]]) {
@@ -7,7 +7,9 @@
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "RNSVGUIKit.h"
#import "RNSVGContainer.h"
#import "RNSVGCGFCRule.h"
#import "RNSVGSvgView.h"
@@ -38,7 +38,7 @@
__block CGRect bounds = CGRectNull;
[self traverseSubviews:^(UIView *node) {
[self traverseSubviews:^(RNSVGView *node) {
if ([node isKindOfClass:[RNSVGMask class]] || [node isKindOfClass:[RNSVGClipPath class]]) {
// no-op
} else if ([node isKindOfClass:[RNSVGNode class]]) {
@@ -160,7 +160,7 @@
return cached;
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
- (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
CGPoint transformed = CGPointApplyAffineTransform(point, self.invmatrix);
transformed = CGPointApplyAffineTransform(transformed, self.invTransform);
@@ -192,7 +192,7 @@
}
}
for (UIView *node in [self.subviews reverseObjectEnumerator]) {
for (RNSVGView *node in [self.subviews reverseObjectEnumerator]) {
if ([node isKindOfClass:[RNSVGNode class]]) {
if ([node isKindOfClass:[RNSVGMask class]]) {
continue;
@@ -201,21 +201,21 @@
if (event) {
svgNode.active = NO;
}
UIView *hitChild = [svgNode hitTest:transformed withEvent:event];
RNSVGPlatformView *hitChild = [svgNode hitTest:transformed withEvent:event];
if (hitChild) {
svgNode.active = YES;
return (svgNode.responsible || (svgNode != hitChild)) ? hitChild : self;
}
} else if ([node isKindOfClass:[RNSVGSvgView class]]) {
RNSVGSvgView* svgView = (RNSVGSvgView*)node;
UIView *hitChild = [svgView hitTest:transformed withEvent:event];
RNSVGPlatformView *hitChild = [svgView hitTest:transformed withEvent:event];
if (hitChild) {
return hitChild;
}
}
}
UIView *hitSelf = [super hitTest:transformed withEvent:event];
RNSVGPlatformView *hitSelf = [super hitTest:transformed withEvent:event];
if (hitSelf) {
return hitSelf;
}
@@ -85,7 +85,7 @@
[self invalidate];
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
- (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
return nil;
}
@@ -13,7 +13,7 @@
@implementation RNSVGMarker
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
- (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
return nil;
}
@@ -12,7 +12,7 @@
@implementation RNSVGMask
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
- (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
return nil;
}
@@ -20,7 +20,7 @@
return self;
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
- (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
return nil;
}
@@ -103,7 +103,7 @@
[self invalidate];
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
- (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
return nil;
}
@@ -6,14 +6,15 @@
* LICENSE file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#import "RNSVGUIKit.h"
#import "RNSVGPainter.h"
#import "RNSVGContainer.h"
#import "RNSVGVBMOS.h"
@class RNSVGNode;
@interface RNSVGSvgView : UIView <RNSVGContainer>
@interface RNSVGSvgView : RNSVGView <RNSVGContainer>
@property (nonatomic, strong) RNSVGLength *bbWidth;
@property (nonatomic, strong) RNSVGLength *bbHeight;
@@ -30,8 +31,6 @@
@property (nonatomic, assign) CGAffineTransform invInitialCTM;
@property (nonatomic, assign) CGAffineTransform viewBoxTransform;
/**
* define <ClipPath></ClipPath> content as clipPath template.
*/
@@ -25,22 +25,24 @@
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
#if !TARGET_OS_OSX // Not available on macOS
// This is necessary to ensure that [self setNeedsDisplay] actually triggers
// a redraw when our parent transitions between hidden and visible.
self.contentMode = UIViewContentModeRedraw;
#endif
rendered = false;
}
return self;
}
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
- (void)insertReactSubview:(RNSVGView *)subview atIndex:(NSInteger)atIndex
{
[super insertReactSubview:subview atIndex:atIndex];
[self insertSubview:subview atIndex:atIndex];
[self invalidate];
}
- (void)removeReactSubview:(UIView *)subview
- (void)removeReactSubview:(RNSVGView *)subview
{
[super removeReactSubview:subview];
[self invalidate];
@@ -66,7 +68,7 @@
- (void)invalidate
{
UIView* parent = self.superview;
RNSVGPlatformView* parent = self.superview;
if ([parent isKindOfClass:[RNSVGNode class]]) {
if (!rendered) {
return;
@@ -190,7 +192,7 @@
_invviewBoxTransform = CGAffineTransformIdentity;
}
for (UIView *node in self.subviews) {
for (RNSVGView *node in self.subviews) {
if ([node isKindOfClass:[RNSVGNode class]]) {
RNSVGNode *svg = (RNSVGNode *)node;
[svg renderTo:context
@@ -203,7 +205,7 @@
- (void)drawRect:(CGRect)rect
{
UIView* parent = self.superview;
RNSVGPlatformView* parent = self.superview;
if ([parent isKindOfClass:[RNSVGNode class]]) {
return;
}
@@ -214,7 +216,7 @@
_boundingBox = rect;
CGContextRef context = UIGraphicsGetCurrentContext();
for (UIView *node in self.subviews) {
for (RNSVGPlatformView *node in self.subviews) {
if ([node isKindOfClass:[RNSVGNode class]]) {
RNSVGNode *svg = (RNSVGNode *)node;
if (svg.responsible && !self.responsible) {
@@ -228,7 +230,7 @@
[self drawToContext:context withRect:rect];
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
- (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
CGPoint transformed = point;
if (self.align) {
@@ -243,7 +245,7 @@
node.active = NO;
}
UIView *hitChild = [node hitTest:transformed withEvent:event];
RNSVGPlatformView *hitChild = [node hitTest:transformed withEvent:event];
if (hitChild) {
node.active = YES;
@@ -279,7 +281,7 @@
return base64;
}
- (void)reactSetInheritedBackgroundColor:(UIColor *)inheritedBackgroundColor
- (void)reactSetInheritedBackgroundColor:(RNSVGColor *)inheritedBackgroundColor
{
self.backgroundColor = inheritedBackgroundColor;
}
@@ -113,7 +113,7 @@
self.frame = bounds;
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
- (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
CGPoint transformed = CGPointApplyAffineTransform(point, self.invmatrix);
transformed = CGPointApplyAffineTransform(transformed, self.invTransform);
RNSVGNode const* template = [self.svgView getDefinedTemplate:self.href];
@@ -122,7 +122,7 @@
} else if (self.active) {
return self;
}
UIView const* hitChild = [template hitTest:transformed withEvent:event];
RNSVGPlatformView const* hitChild = [template hitTest:transformed withEvent:event];
if (hitChild) {
self.active = YES;
return self;
+3 -3
View File
@@ -13,11 +13,11 @@
@class RNSVGGroup;
/**
* RNSVG nodes are implemented as base UIViews. They should be implementation for all basic
* RNSVG nodes are implemented as base NSViews/UIViews. They should be implementation for all basic
interfaces for all non-definition nodes.
*/
@interface RNSVGNode : UIView
@interface RNSVGNode : RNSVGView
/*
N[1/Sqrt[2], 36]
@@ -132,7 +132,7 @@ extern CGFloat const RNSVG_DEFAULT_FONT_SIZE;
- (void)endTransparencyLayer:(CGContextRef)context;
- (void)traverseSubviews:(BOOL (^)(__kindof UIView *node))block;
- (void)traverseSubviews:(BOOL (^)(__kindof RNSVGView *node))block;
- (void)clearChildCache;
+13 -9
View File
@@ -46,14 +46,14 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
return self;
}
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
- (void)insertReactSubview:(RNSVGView *)subview atIndex:(NSInteger)atIndex
{
[super insertReactSubview:subview atIndex:atIndex];
[self insertSubview:subview atIndex:atIndex];
[self invalidate];
}
- (void)removeReactSubview:(UIView *)subview
- (void)removeReactSubview:(RNSVGView *)subview
{
[super removeReactSubview:subview];
[self invalidate];
@@ -98,7 +98,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
{
RNSVGNode* node = self;
while (node != nil) {
UIView* parent = [node superview];
RNSVGPlatformView* parent = [node superview];
if (![parent isKindOfClass:[RNSVGNode class]]) {
return;
@@ -124,7 +124,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
break;
}
UIView* parent = [node superview];
RNSVGPlatformView* parent = [node superview];
if (![node isKindOfClass:[RNSVGNode class]]) {
node = nil;
@@ -160,7 +160,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
return [glyphContext getFontSize];
}
- (void)reactSetInheritedBackgroundColor:(UIColor *)inheritedBackgroundColor
- (void)reactSetInheritedBackgroundColor:(RNSVGColor *)inheritedBackgroundColor
{
self.backgroundColor = inheritedBackgroundColor;
}
@@ -170,7 +170,11 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
_pointerEvents = pointerEvents;
self.userInteractionEnabled = (pointerEvents != RCTPointerEventsNone);
if (pointerEvents == RCTPointerEventsBoxNone) {
#if TARGET_OS_OSX
self.accessibilityModal = NO;
#else
self.accessibilityViewIsModal = NO;
#endif
}
}
@@ -390,7 +394,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
}
// hitTest delagate
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
- (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
// abstract
@@ -403,7 +407,7 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
return _svgView;
}
__kindof UIView *parent = self.superview;
__kindof RNSVGPlatformView *parent = self.superview;
if ([parent class] == [RNSVGSvgView class]) {
_svgView = parent;
@@ -587,9 +591,9 @@ CGFloat const RNSVG_DEFAULT_FONT_SIZE = 12;
}
}
- (void)traverseSubviews:(BOOL (^)(__kindof UIView *node))block
- (void)traverseSubviews:(BOOL (^)(__kindof RNSVGView *node))block
{
for (UIView *node in self.subviews) {
for (RNSVGView *node in self.subviews) {
if (!block(node)) {
break;
}
@@ -8,6 +8,8 @@
#import <Foundation/Foundation.h>
#import "RNSVGUIKit.h"
#import "RNSVGBrush.h"
#import "RNSVGCGFCRule.h"
#import "RNSVGNode.h"
@@ -513,7 +513,7 @@ UInt32 saturate(CGFloat value) {
}
// hitTest delegate
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
- (RNSVGPlatformView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
if (!_hitArea) {
return nil;
+42
View File
@@ -0,0 +1,42 @@
// Most (if not all) of this file could probably go away once react-native-macos's version of RCTUIKit.h makes its way upstream.
// https://github.com/microsoft/react-native-macos/issues/242
#if !TARGET_OS_OSX
#import <UIKit/UIKit.h>
#define RNSVGColor UIColor
#define RNSVGPlatformView UIView
#define RNSVGTextView UILabel
#define RNSVGView UIView
#else // TARGET_OS_OSX [
#import <React/RCTUIKit.h>
#define RNSVGColor NSColor
#define RNSVGPlatformView NSView
#define RNSVGTextView NSTextView
@interface RNSVGView : RCTUIView
@property CGPoint center;
@property (nonatomic, strong) RNSVGColor *tintColor;
@end
// TODO: These could probably be a part of react-native-macos
// See https://github.com/microsoft/react-native-macos/issues/658 and https://github.com/microsoft/react-native-macos/issues/659
@interface NSImage (RNSVGMacOSExtensions)
@property (readonly) CGImageRef CGImage;
@end
@interface NSValue (RNSVGMacOSExtensions)
+ (NSValue *)valueWithCGAffineTransform:(CGAffineTransform)transform;
+ (NSValue *)valueWithCGPoint:(CGPoint)point;
@property (readonly) CGAffineTransform CGAffineTransformValue;
@property (readonly) CGPoint CGPointValue;
@end
#endif // ] TARGET_OS_OSX
+86
View File
@@ -0,0 +1,86 @@
#import "RNSVGUIKit.h"
@implementation RNSVGView
{
NSColor *_tintColor;
}
- (CGPoint)center
{
NSRect frameRect = self.frame;
CGFloat xCenter = frameRect.origin.x + frameRect.size.width / 2;
CGFloat yCenter = frameRect.origin.y + frameRect.size.height / 2;
return CGPointMake(xCenter, yCenter);
}
- (void)setCenter:(CGPoint)point
{
NSRect frameRect = self.frame;
CGFloat xOrigin = frameRect.origin.x - frameRect.size.width / 2;
CGFloat yOrigin = frameRect.origin.y - frameRect.size.height / 2;
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)
- (CGImageRef) CGImage
{
return [self CGImageForProposedRect:NULL context:NULL hints:NULL];
}
@end
@implementation NSValue (RNSVGMacOSExtensions)
+ (NSValue *)valueWithCGAffineTransform:(CGAffineTransform)transform
{
return [NSValue valueWithBytes:&transform objCType:@encode(CGAffineTransform)];
}
+ (NSValue *)valueWithCGPoint:(CGPoint)point
{
return [NSValue valueWithBytes:&point objCType:@encode(CGPoint)];
}
- (CGAffineTransform)CGAffineTransformValue
{
CGAffineTransform value;
[self getValue:&value];
return value;
}
- (CGPoint)CGPointValue
{
CGPoint value;
[self getValue:&value];
return value;
}
@end
@@ -1,5 +1,6 @@
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "RNSVGUIKit.h"
#import "RNSVGTextProperties.h"
#import "RNSVGPropHelper.h"
@@ -5,9 +5,12 @@
* This source code is licensed under the MIT-style license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <CoreText/CoreText.h>
#import "RNSVGUIKit.h"
#import "RNSVGText.h"
@interface RNSVGTSpan : RNSVGText
@@ -6,36 +6,17 @@
* LICENSE file in the root directory of this source tree.
*/
#import "RNSVGTSpan.h"
#import "RNSVGUIKit.h"
#import "RNSVGText.h"
#import "RNSVGTextPath.h"
#import "RNSVGTextProperties.h"
#import "RNSVGTopAlignedLabel.h"
#import "RNSVGPathMeasure.h"
#import "RNSVGFontData.h"
static NSCharacterSet *RNSVGTSpan_separators = nil;
static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI;
@interface TopAlignedLabel : UILabel
@end
@implementation TopAlignedLabel
- (void)drawTextInRect:(CGRect) rect
{
NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:self.text attributes:@{NSFontAttributeName:self.font}];
rect.size.height = [attributedText boundingRectWithSize:rect.size
options:NSStringDrawingUsesLineFragmentOrigin
context:nil].size.height;
if (self.numberOfLines != 0) {
rect.size.height = MIN(rect.size.height, self.numberOfLines * self.font.lineHeight);
}
[super drawTextInRect:rect];
}
@end
@implementation RNSVGTSpan
{
CGFloat startOffset;
@@ -116,7 +97,7 @@ static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI;
NSUInteger count = [emoji count];
CGFloat fontSize = [gc getFontSize];
for (NSUInteger i = 0; i < count; i++) {
UILabel *label = [emoji objectAtIndex:i];
RNSVGPlatformView *label = [emoji objectAtIndex:i];
NSValue *transformValue = [emojiTransform objectAtIndex:i];
CGAffineTransform transform = [transformValue CGAffineTransformValue];
CGContextConcatCTM(context, transform);
@@ -163,7 +144,7 @@ static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI;
return attrs;
}
TopAlignedLabel *label;
RNSVGTopAlignedLabel *label;
- (void)drawWrappedText:(CGContextRef)context gc:(RNSVGGlyphContext *)gc rect:(CGRect)rect color:(CGColorRef)color {
[self pushGlyphContext];
if (fontRef != nil) {
@@ -198,17 +179,18 @@ TopAlignedLabel *label;
UIFont *font = (__bridge UIFont *)(fontRef);
if (!label) {
label = [[TopAlignedLabel alloc] init];
label = [[RNSVGTopAlignedLabel alloc] init];
}
label.attributedText = (__bridge NSAttributedString * _Nullable)(attrString);
label.baselineAdjustment = UIBaselineAdjustmentNone;
label.lineBreakMode = NSLineBreakByWordWrapping;
label.backgroundColor = UIColor.clearColor;
label.backgroundColor = RNSVGColor.clearColor;
label.textAlignment = align;
label.numberOfLines = 0;
#if !TARGET_OS_OSX // On macOS, views are transparent by default
label.opaque = NO;
#endif
label.font = font;
label.textColor = [UIColor colorWithCGColor:color];
label.textColor = [RNSVGColor colorWithCGColor:color];
CGFloat fontSize = [gc getFontSize];
CGFloat height = CGRectGetHeight(rect);
@@ -279,7 +261,7 @@ TopAlignedLabel *label;
NSString *str = self.content;
if (!str) {
for (UIView *node in self.subviews) {
for (RNSVGView *node in self.subviews) {
if ([node isKindOfClass:[RNSVGText class]]) {
RNSVGText *text = (RNSVGText*)node;
advance += [text getSubtreeTextChunksTotalAdvance];
@@ -1008,14 +990,18 @@ TopAlignedLabel *label;
CGFloat width = box.size.width;
if (width == 0) { // Render unicode emoji
UILabel *label = [[UILabel alloc] init];
RNSVGTextView *label = [[RNSVGTextView alloc] init];
CFIndex startIndex = indices[g];
long len = MAX(1, endIndex - startIndex);
NSRange range = NSMakeRange(startIndex, len);
NSString* currChars = [str substringWithRange:range];
#if TARGET_OS_OSX
label.string = currChars;
#else
label.text = currChars;
label.opaque = NO;
label.backgroundColor = UIColor.clearColor;
#endif
label.backgroundColor = RNSVGColor.clearColor;
UIFont * customFont = [UIFont systemFontOfSize:fontSize];
CGSize measuredSize = [currChars sizeWithAttributes:
@@ -196,7 +196,7 @@
return _alignmentBaseline;
}
UIView* parent = self.superview;
RNSVGPlatformView* parent = self.superview;
while (parent != nil) {
if ([parent isKindOfClass:[RNSVGText class]]) {
RNSVGText* node = (RNSVGText*)parent;
@@ -221,7 +221,7 @@
return _baselineShift;
}
UIView* parent = [self superview];
RNSVGPlatformView* parent = [self superview];
while (parent != nil) {
if ([parent isKindOfClass:[RNSVGText class]]) {
RNSVGText* node = (RNSVGText*)parent;
@@ -271,7 +271,7 @@
RNSVGGlyphContext* gc = [self.textRoot getGlyphContext];
NSArray* font = [gc getFontContext];
RNSVGText* node = self;
UIView* parent = [self superview];
RNSVGPlatformView* parent = [self superview];
for (NSInteger i = [font count] - 1; i >= 0; i--) {
RNSVGFontData* fontData = [font objectAtIndex:i];
if (![parent isKindOfClass:[RNSVGText class]] ||
@@ -291,7 +291,7 @@
return cachedAdvance;
}
CGFloat advance = 0;
for (UIView *node in self.subviews) {
for (RNSVGView *node in self.subviews) {
if ([node isKindOfClass:[RNSVGText class]]) {
RNSVGText *text = (RNSVGText*)node;
advance += [text getSubtreeTextChunksTotalAdvance];
+13
View File
@@ -0,0 +1,13 @@
#if TARGET_OS_OSX
#import <React/RCTTextView.h>
@interface RNSVGTopAlignedLabel : NSTextView
@property NSAttributedString *attributedText;
@property NSLineBreakMode lineBreakMode;
@property NSInteger numberOfLines;
@property NSString *text;
@property NSTextAlignment textAlignment;
#else
@interface RNSVGTopAlignedLabel : UILabel
#endif
@end
+17
View File
@@ -0,0 +1,17 @@
#import "RNSVGTopAlignedLabel.h"
@implementation RNSVGTopAlignedLabel
- (void)drawTextInRect:(CGRect) rect
{
NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:self.text attributes:@{NSFontAttributeName:self.font}];
rect.size.height = [attributedText boundingRectWithSize:rect.size
options:NSStringDrawingUsesLineFragmentOrigin
context:nil].size.height;
if (self.numberOfLines != 0) {
rect.size.height = MIN(rect.size.height, self.numberOfLines * self.font.lineHeight);
}
[super drawTextInRect:rect];
}
@end
+55
View File
@@ -0,0 +1,55 @@
#import "RNSVGTopAlignedLabel.h"
@implementation RNSVGTopAlignedLabel
- (NSAttributedString *)attributedText
{
return self.attributedString;
}
- (NSLineBreakMode)lineBreakMode
{
return self.textContainer.lineBreakMode;
}
- (NSInteger)numberOfLines
{
return self.textContainer.maximumNumberOfLines;
}
- (NSString *)text
{
return self.string;
}
- (NSTextAlignment)textAlignment
{
return self.alignment;
}
- (void)setAttributedText:(NSAttributedString *)attributedString
{
[self.textStorage setAttributedString:attributedString];
}
- (void)setLineBreakMode:(NSLineBreakMode)lineBreakMode
{
self.textContainer.lineBreakMode = lineBreakMode;
}
- (void)setNumberOfLines:(NSInteger)numberOfLines
{
self.textContainer.maximumNumberOfLines = numberOfLines;
}
- (void)setText:(NSString *)text
{
self.string = text;
}
- (void)setTextAlignment:(NSTextAlignment)textAlignment
{
self.alignment = textAlignment;
}
@end
@@ -4,9 +4,10 @@
https://github.com/erica/iOS-Drawing/tree/master/C08/Quartz%20Book%20Pack/Bezier
*/
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "RNSVGUIKit.h"
#define RNSVGNULLPOINT CGRectNull.origin
@interface RNSVGBezierElement : NSObject
@@ -1,4 +1,4 @@
#import <UIKit/UIKit.h>
#import "RNSVGUIKit.h"
#ifndef RNSVGLength_h
#define RNSVGLength_h
@@ -1,7 +1,7 @@
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "RNSVGUIKit.h"
typedef enum RNSVGMarkerType {
kStartMarker,
kMidMarker,
@@ -6,7 +6,7 @@
* LICENSE file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#import "RNSVGUIKit.h"
@interface RNSVGPathMeasure : NSObject
@@ -6,8 +6,7 @@
* LICENSE file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#import "RNSVGUIKit.h"
@interface RNSVGPathParser : NSObject
@@ -6,7 +6,8 @@
* LICENSE file in the root directory of this source tree.
*/
#import <UIKit/UIKit.h>
#import "RNSVGUIKit.h"
#import "RNSVGVBMOS.h"
@interface RNSVGViewBox : NSObject
@@ -18,7 +18,7 @@ RCT_EXPORT_MODULE()
return [RNSVGDefs new];
}
- (UIView *)view
- (RNSVGView *)view
{
return [self node];
}

Some files were not shown because too many files have changed in this diff Show More