mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-08-16 02:44:58 +00:00
Implement kerning, ligatures, etc., and cleanup; in ios.
Implement hasGlyph ligature helper. Export view property setters for: text: textLength, baselineShift, lengthAdjust, alignmentBaseline, textPath: side, method, midLine, spacing. Attempt to fix alignmentBaseline and baselineShift, but both properties are nil at all times, I must be missing something.
This commit is contained in:
@@ -13,7 +13,6 @@
|
||||
#import "RNSVGSvgView.h"
|
||||
#import "RNSVGPath.h"
|
||||
#import "GlyphContext.h"
|
||||
#import "RNSVGGlyphContext.h"
|
||||
|
||||
@interface RNSVGGroup : RNSVGPath <RNSVGContainer>
|
||||
|
||||
@@ -22,7 +21,6 @@
|
||||
- (void)renderPathTo:(CGContextRef)context;
|
||||
- (void)renderGroupTo:(CGContextRef)context;
|
||||
|
||||
- (RNSVGGlyphContext *)getRNSVGGlyphContext;
|
||||
- (GlyphContext *)getGlyphContext;
|
||||
- (void)pushGlyphContext;
|
||||
- (void)popGlyphContext;
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
@implementation RNSVGGroup
|
||||
{
|
||||
GlyphContext *_glyphContext;
|
||||
RNSVGGlyphContext *_RNSVGGlyphContext;
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
@@ -52,17 +51,10 @@
|
||||
CGFloat width = CGRectGetWidth(clipBounds);
|
||||
CGFloat height = CGRectGetHeight(clipBounds);
|
||||
|
||||
_RNSVGGlyphContext = [[RNSVGGlyphContext alloc] initWithDimensions:width
|
||||
height:height];
|
||||
_glyphContext = [[GlyphContext alloc] initWithScale:1 width:width
|
||||
height:height];
|
||||
}
|
||||
|
||||
- (RNSVGGlyphContext *)getRNSVGGlyphContext
|
||||
{
|
||||
return _RNSVGGlyphContext;
|
||||
}
|
||||
|
||||
- (GlyphContext *)getGlyphContext
|
||||
{
|
||||
return _glyphContext;
|
||||
@@ -70,13 +62,11 @@
|
||||
|
||||
- (void)pushGlyphContext
|
||||
{
|
||||
//[[[self getTextRoot] getRNSVGGlyphContext] pushContext:self.font];
|
||||
[[[self getTextRoot] getGlyphContext] pushContextWithRNSVGGroup:self font:self.font];
|
||||
}
|
||||
|
||||
- (void)popGlyphContext
|
||||
{
|
||||
//[[[self getTextRoot] getRNSVGGlyphContext] popContext];
|
||||
[[[self getTextRoot] getGlyphContext] popContext];
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
1023B4901D3DF4C40051496D /* RNSVGDefs.m in Sources */ = {isa = PBXBuildFile; fileRef = 1023B48F1D3DF4C40051496D /* RNSVGDefs.m */; };
|
||||
1023B4931D3DF5060051496D /* RNSVGUse.m in Sources */ = {isa = PBXBuildFile; fileRef = 1023B4921D3DF5060051496D /* RNSVGUse.m */; };
|
||||
1023B4961D3DF57D0051496D /* RNSVGUseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1023B4951D3DF57D0051496D /* RNSVGUseManager.m */; };
|
||||
103371321D41C5C90028AF13 /* RNSVGBezierTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 103371311D41C5C90028AF13 /* RNSVGBezierTransformer.m */; };
|
||||
1039D2891CE71EB7001E90A8 /* RNSVGGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2821CE71EB7001E90A8 /* RNSVGGroup.m */; };
|
||||
1039D28A1CE71EB7001E90A8 /* RNSVGImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2841CE71EB7001E90A8 /* RNSVGImage.m */; };
|
||||
1039D28B1CE71EB7001E90A8 /* RNSVGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2861CE71EB7001E90A8 /* RNSVGPath.m */; };
|
||||
@@ -54,7 +53,6 @@
|
||||
7FC260CE1E3499BC00A39833 /* RNSVGViewBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FC260CD1E3499BC00A39833 /* RNSVGViewBox.m */; };
|
||||
7FC260D11E34A12000A39833 /* RNSVGSymbol.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FC260D01E34A12000A39833 /* RNSVGSymbol.m */; };
|
||||
7FC260D41E34A12A00A39833 /* RNSVGSymbolManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FC260D31E34A12A00A39833 /* RNSVGSymbolManager.m */; };
|
||||
7FFC4EA41E24E5AD00AD5BE5 /* RNSVGGlyphContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FFC4EA31E24E5AD00AD5BE5 /* RNSVGGlyphContext.m */; };
|
||||
945A8AE11F4CBFD1004BBF6B /* Drawing-Text.m in Sources */ = {isa = PBXBuildFile; fileRef = 945A8ADF1F4CBFD1004BBF6B /* Drawing-Text.m */; };
|
||||
945A8AE21F4CBFD1004BBF6B /* UIBezierPath+Text.m in Sources */ = {isa = PBXBuildFile; fileRef = 945A8AE01F4CBFD1004BBF6B /* UIBezierPath+Text.m */; };
|
||||
945A8AE41F4CC01D004BBF6B /* UIBezierPath+Elements.m in Sources */ = {isa = PBXBuildFile; fileRef = 945A8AE31F4CC01D004BBF6B /* UIBezierPath+Elements.m */; };
|
||||
@@ -108,7 +106,6 @@
|
||||
A361E7711EB0C33D00646005 /* RNSVGCircleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D1D1CE74E3100887C2B /* RNSVGCircleManager.m */; };
|
||||
A361E7721EB0C33D00646005 /* RNSVGLinearGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BEC1B91D3F66F500FDCB19 /* RNSVGLinearGradient.m */; };
|
||||
A361E7731EB0C33D00646005 /* RNSVGPercentageConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2AF1CE72F27001E90A8 /* RNSVGPercentageConverter.m */; };
|
||||
A361E7741EB0C33D00646005 /* RNSVGGlyphContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FFC4EA31E24E5AD00AD5BE5 /* RNSVGGlyphContext.m */; };
|
||||
A361E7751EB0C33D00646005 /* RNSVGEllipse.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D431CE74E3D00887C2B /* RNSVGEllipse.m */; };
|
||||
A361E7761EB0C33D00646005 /* RNSVGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2861CE71EB7001E90A8 /* RNSVGPath.m */; };
|
||||
A361E7771EB0C33D00646005 /* RNSVGTextPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F08CE9D1E23479700650F83 /* RNSVGTextPath.m */; };
|
||||
@@ -125,7 +122,6 @@
|
||||
A361E7821EB0C33D00646005 /* RNSVGSvgViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D311CE74E3100887C2B /* RNSVGSvgViewManager.m */; };
|
||||
A361E7831EB0C33D00646005 /* RNSVGSolidColorBrush.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF41AF0549300FF9E5C /* RNSVGSolidColorBrush.m */; };
|
||||
A361E7841EB0C33D00646005 /* RNSVGPathManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D291CE74E3100887C2B /* RNSVGPathManager.m */; };
|
||||
A361E7851EB0C33D00646005 /* RNSVGBezierTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 103371311D41C5C90028AF13 /* RNSVGBezierTransformer.m */; };
|
||||
A361E7861EB0C33D00646005 /* RNSVGRenderableManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D2D1CE74E3100887C2B /* RNSVGRenderableManager.m */; };
|
||||
A361E7871EB0C33D00646005 /* RNSVGRadialGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BEC1BB1D3F66F500FDCB19 /* RNSVGRadialGradient.m */; };
|
||||
A361E7881EB0C33D00646005 /* RNSVGRadialGradientManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BEC1C11D3F680F00FDCB19 /* RNSVGRadialGradientManager.m */; };
|
||||
@@ -206,8 +202,6 @@
|
||||
1023B4921D3DF5060051496D /* RNSVGUse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGUse.m; path = Elements/RNSVGUse.m; sourceTree = "<group>"; };
|
||||
1023B4941D3DF57D0051496D /* RNSVGUseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGUseManager.h; sourceTree = "<group>"; };
|
||||
1023B4951D3DF57D0051496D /* RNSVGUseManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGUseManager.m; sourceTree = "<group>"; };
|
||||
103371311D41C5C90028AF13 /* RNSVGBezierTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGBezierTransformer.m; path = Text/RNSVGBezierTransformer.m; sourceTree = "<group>"; };
|
||||
103371331D41D3400028AF13 /* RNSVGBezierTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGBezierTransformer.h; path = Text/RNSVGBezierTransformer.h; sourceTree = "<group>"; };
|
||||
1039D2811CE71EB7001E90A8 /* RNSVGGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGGroup.h; path = Elements/RNSVGGroup.h; sourceTree = "<group>"; };
|
||||
1039D2821CE71EB7001E90A8 /* RNSVGGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGGroup.m; path = Elements/RNSVGGroup.m; sourceTree = "<group>"; };
|
||||
1039D2831CE71EB7001E90A8 /* RNSVGImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGImage.h; path = Elements/RNSVGImage.h; sourceTree = "<group>"; };
|
||||
@@ -293,8 +287,6 @@
|
||||
7FC260D01E34A12000A39833 /* RNSVGSymbol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGSymbol.m; path = Elements/RNSVGSymbol.m; sourceTree = "<group>"; };
|
||||
7FC260D21E34A12A00A39833 /* RNSVGSymbolManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGSymbolManager.h; sourceTree = "<group>"; };
|
||||
7FC260D31E34A12A00A39833 /* RNSVGSymbolManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGSymbolManager.m; sourceTree = "<group>"; };
|
||||
7FFC4EA21E24E52500AD5BE5 /* RNSVGGlyphContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNSVGGlyphContext.h; path = Text/RNSVGGlyphContext.h; sourceTree = "<group>"; };
|
||||
7FFC4EA31E24E5AD00AD5BE5 /* RNSVGGlyphContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGGlyphContext.m; path = Text/RNSVGGlyphContext.m; sourceTree = "<group>"; };
|
||||
945A8ADD1F4CB7F9004BBF6B /* QuartzBookPack */ = {isa = PBXFileReference; lastKnownFileType = folder; path = QuartzBookPack; sourceTree = "<group>"; };
|
||||
945A8ADF1F4CBFD1004BBF6B /* Drawing-Text.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "Drawing-Text.m"; path = "QuartzBookPack/TextDrawing/Drawing-Text.m"; sourceTree = "<group>"; };
|
||||
945A8AE01F4CBFD1004BBF6B /* UIBezierPath+Text.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "UIBezierPath+Text.m"; path = "QuartzBookPack/TextDrawing/UIBezierPath+Text.m"; sourceTree = "<group>"; };
|
||||
@@ -506,10 +498,6 @@
|
||||
9494C51A1F4B605F00D5BCFD /* GlyphContext.m */,
|
||||
9494C4EF1F4B5BE700D5BCFD /* PropHelper.h */,
|
||||
9494C4F01F4B5BE700D5BCFD /* PropHelper.m */,
|
||||
103371331D41D3400028AF13 /* RNSVGBezierTransformer.h */,
|
||||
103371311D41C5C90028AF13 /* RNSVGBezierTransformer.m */,
|
||||
7FFC4EA21E24E52500AD5BE5 /* RNSVGGlyphContext.h */,
|
||||
7FFC4EA31E24E5AD00AD5BE5 /* RNSVGGlyphContext.m */,
|
||||
1039D28F1CE71EC2001E90A8 /* RNSVGText.h */,
|
||||
1039D2901CE71EC2001E90A8 /* RNSVGText.m */,
|
||||
7F08CE9C1E23479700650F83 /* RNSVGTextPath.h */,
|
||||
@@ -718,7 +706,6 @@
|
||||
10BEC1BC1D3F66F500FDCB19 /* RNSVGLinearGradient.m in Sources */,
|
||||
9494C5461F4C44DD00D5BCFD /* TextPathSide.m in Sources */,
|
||||
1039D2B01CE72F27001E90A8 /* RNSVGPercentageConverter.m in Sources */,
|
||||
7FFC4EA41E24E5AD00AD5BE5 /* RNSVGGlyphContext.m in Sources */,
|
||||
9494C53C1F4C44DD00D5BCFD /* TextAnchor.m in Sources */,
|
||||
10BA0D491CE74E3D00887C2B /* RNSVGEllipse.m in Sources */,
|
||||
9494C5051F4B5BE800D5BCFD /* FontWeight.m in Sources */,
|
||||
@@ -740,7 +727,6 @@
|
||||
10BA0D3E1CE74E3100887C2B /* RNSVGSvgViewManager.m in Sources */,
|
||||
0CF68B0F1AF0549300FF9E5C /* RNSVGSolidColorBrush.m in Sources */,
|
||||
10BA0D3A1CE74E3100887C2B /* RNSVGPathManager.m in Sources */,
|
||||
103371321D41C5C90028AF13 /* RNSVGBezierTransformer.m in Sources */,
|
||||
10BA0D3C1CE74E3100887C2B /* RNSVGRenderableManager.m in Sources */,
|
||||
10BEC1BD1D3F66F500FDCB19 /* RNSVGRadialGradient.m in Sources */,
|
||||
10BEC1C31D3F680F00FDCB19 /* RNSVGRadialGradientManager.m in Sources */,
|
||||
@@ -786,7 +772,6 @@
|
||||
A361E7711EB0C33D00646005 /* RNSVGCircleManager.m in Sources */,
|
||||
A361E7721EB0C33D00646005 /* RNSVGLinearGradient.m in Sources */,
|
||||
A361E7731EB0C33D00646005 /* RNSVGPercentageConverter.m in Sources */,
|
||||
A361E7741EB0C33D00646005 /* RNSVGGlyphContext.m in Sources */,
|
||||
9494C53F1F4C44DD00D5BCFD /* TextDecoration.m in Sources */,
|
||||
A361E7751EB0C33D00646005 /* RNSVGEllipse.m in Sources */,
|
||||
A361E7761EB0C33D00646005 /* RNSVGPath.m in Sources */,
|
||||
@@ -809,7 +794,6 @@
|
||||
A361E7831EB0C33D00646005 /* RNSVGSolidColorBrush.m in Sources */,
|
||||
9494C5391F4C44DD00D5BCFD /* FontStyle.m in Sources */,
|
||||
A361E7841EB0C33D00646005 /* RNSVGPathManager.m in Sources */,
|
||||
A361E7851EB0C33D00646005 /* RNSVGBezierTransformer.m in Sources */,
|
||||
A361E7861EB0C33D00646005 /* RNSVGRenderableManager.m in Sources */,
|
||||
A361E7871EB0C33D00646005 /* RNSVGRadialGradient.m in Sources */,
|
||||
945A8AF91F4CE3E8004BBF6B /* AlignmentBaseline.m in Sources */,
|
||||
|
||||
@@ -10,14 +10,12 @@
|
||||
#import "RNSVGContainer.h"
|
||||
#import "RNSVGClipPath.h"
|
||||
#import "RNSVGGroup.h"
|
||||
#import "RNSVGGlyphContext.h"
|
||||
#import "GlyphContext.h"
|
||||
|
||||
@implementation RNSVGNode
|
||||
{
|
||||
RNSVGGroup *_textRoot;
|
||||
GlyphContext *glyphContext;
|
||||
RNSVGGlyphContext *RNSVGGlyphContext;
|
||||
BOOL _transparent;
|
||||
CGPathRef _cachedClipPath;
|
||||
RNSVGSvgView *_svgView;
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/**
|
||||
* 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 <UIKit/UIKit.h>
|
||||
|
||||
@interface RNSVGBezierTransformer : NSObject
|
||||
|
||||
- (instancetype)initWithBezierCurvesAndStartOffset:(NSArray<NSArray *> *)bezierCurves startOffset:(CGFloat)startOffset;
|
||||
- (CGAffineTransform)getTransformAtDistance:(CGFloat)distance;
|
||||
- (BOOL)hasReachedEnd;
|
||||
- (BOOL)hasReachedStart;
|
||||
|
||||
@end
|
||||
@@ -1,147 +0,0 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* based on CurvyText by iosptl: https://github.com/iosptl/ios7ptl/blob/master/ch21-Text/CurvyText/CurvyText/CurvyTextView.m
|
||||
*/
|
||||
|
||||
#import "RNSVGBezierTransformer.h"
|
||||
|
||||
@implementation RNSVGBezierTransformer
|
||||
{
|
||||
NSArray<NSArray *> *_bezierCurves;
|
||||
int _currentBezierIndex;
|
||||
CGFloat _startOffset;
|
||||
CGFloat _lastOffset;
|
||||
CGFloat _lastRecord;
|
||||
CGFloat _lastDistance;
|
||||
CGPoint _lastPoint;
|
||||
CGPoint _P0;
|
||||
CGPoint _P1;
|
||||
CGPoint _P2;
|
||||
CGPoint _P3;
|
||||
BOOL _reachedEnd;
|
||||
BOOL _reachedStart;
|
||||
}
|
||||
|
||||
- (instancetype)initWithBezierCurvesAndStartOffset:(NSArray<NSArray *> *)bezierCurves startOffset:(CGFloat)startOffset
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_bezierCurves = bezierCurves;
|
||||
_currentBezierIndex = _lastOffset = _lastRecord = _lastDistance = 0;
|
||||
_startOffset = startOffset;
|
||||
[self setControlPoints];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
static CGFloat calculateBezier(CGFloat t, CGFloat P0, CGFloat P1, CGFloat P2, CGFloat P3) {
|
||||
return (1-t)*(1-t)*(1-t)*P0+3*(1-t)*(1-t)*t*P1+3*(1-t)*t*t*P2+t*t*t*P3;
|
||||
}
|
||||
|
||||
- (CGPoint)pointAtOffset:(CGFloat)t {
|
||||
CGFloat x = calculateBezier(t, _P0.x, _P1.x, _P2.x, _P3.x);
|
||||
CGFloat y = calculateBezier(t, _P0.y, _P1.y, _P2.y, _P3.y);
|
||||
return CGPointMake(x, y);
|
||||
}
|
||||
|
||||
static CGFloat calculateBezierPrime(CGFloat t, CGFloat P0, CGFloat P1, CGFloat P2, CGFloat P3) {
|
||||
return -3*(1-t)*(1-t)*P0+(3*(1-t)*(1-t)*P1)-(6*t*(1-t)*P1)-(3*t*t*P2)+(6*t*(1-t)*P2)+3*t*t*P3;
|
||||
}
|
||||
|
||||
- (CGFloat)angleAtOffset:(CGFloat)t {
|
||||
CGFloat dx = calculateBezierPrime(t, _P0.x, _P1.x, _P2.x, _P3.x);
|
||||
CGFloat dy = calculateBezierPrime(t, _P0.y, _P1.y, _P2.y, _P3.y);
|
||||
return atan2(dy, dx);
|
||||
}
|
||||
|
||||
static CGFloat calculateDistance(CGPoint a, CGPoint b) {
|
||||
return hypot(a.x - b.x, a.y - b.y);
|
||||
}
|
||||
|
||||
// Simplistic routine to find the offset along Bezier that is
|
||||
// `distance` away from `point`. `offset` is the offset used to
|
||||
// generate `point`, and saves us the trouble of recalculating it
|
||||
// This routine just walks forward until it finds a point at least
|
||||
// `distance` away. Good optimizations here would reduce the number
|
||||
// of guesses, but this is tricky since if we go too far out, the
|
||||
// curve might loop back on leading to incorrect results. Tuning
|
||||
// kStep is good start.
|
||||
- (CGFloat)offsetAtDistance:(CGFloat)distance
|
||||
fromPoint:(CGPoint)point
|
||||
offset:(CGFloat)offset {
|
||||
|
||||
const CGFloat kStep = 0.001; // 0.0001 - 0.001 work well
|
||||
CGFloat newDistance = 0;
|
||||
CGFloat newOffset = offset + kStep;
|
||||
while (newDistance <= distance && newOffset < 1.0) {
|
||||
newOffset += kStep;
|
||||
newDistance = calculateDistance(point, [self pointAtOffset:newOffset]);
|
||||
}
|
||||
|
||||
_lastDistance = newDistance;
|
||||
return newOffset;
|
||||
}
|
||||
|
||||
- (void)setControlPoints
|
||||
{
|
||||
NSArray *bezier = [_bezierCurves objectAtIndex:_currentBezierIndex++];
|
||||
|
||||
// set start point
|
||||
if (bezier.count == 1) {
|
||||
_lastPoint = _P0 = [[bezier objectAtIndex:0] CGPointValue];
|
||||
[self setControlPoints];
|
||||
} else if (bezier.count == 3) {
|
||||
_P1 = [[bezier objectAtIndex:0] CGPointValue];
|
||||
_P2 = [[bezier objectAtIndex:1] CGPointValue];
|
||||
_P3 = [[bezier objectAtIndex:2] CGPointValue];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (CGAffineTransform)getTransformAtDistance:(CGFloat)distance
|
||||
{
|
||||
distance += _startOffset;
|
||||
_reachedStart = distance >= 0;
|
||||
if (_reachedEnd || !_reachedStart) {
|
||||
return CGAffineTransformIdentity;
|
||||
}
|
||||
|
||||
CGFloat offset = [self offsetAtDistance:distance - _lastRecord
|
||||
fromPoint:_lastPoint
|
||||
offset:_lastOffset];
|
||||
|
||||
if (offset < 1) {
|
||||
CGPoint glyphPoint = [self pointAtOffset:offset];
|
||||
_lastOffset = offset;
|
||||
_lastPoint = glyphPoint;
|
||||
_lastRecord = distance;
|
||||
return CGAffineTransformRotate(CGAffineTransformMakeTranslation(glyphPoint.x, glyphPoint.y), [self angleAtOffset:offset]);
|
||||
} else if (_bezierCurves.count == _currentBezierIndex) {
|
||||
_reachedEnd = YES;
|
||||
return CGAffineTransformIdentity;
|
||||
} else {
|
||||
_lastOffset = 0;
|
||||
_lastPoint = _P0 = _P3;
|
||||
_lastRecord += _lastDistance;
|
||||
[self setControlPoints];
|
||||
return [self getTransformAtDistance:distance - _startOffset];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)hasReachedEnd
|
||||
{
|
||||
return _reachedEnd;
|
||||
}
|
||||
|
||||
- (BOOL)hasReachedStart
|
||||
{
|
||||
return _reachedStart;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* 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 <React/UIView+React.h>
|
||||
#import <CoreText/CoreText.h>
|
||||
#import "RNSVGPercentageConverter.h"
|
||||
|
||||
@interface RNSVGGlyphContext : NSObject
|
||||
|
||||
- (instancetype)initWithDimensions:(CGFloat)width height:(CGFloat)height;
|
||||
|
||||
- (CGFloat)getWidth;
|
||||
- (CGFloat)getHeight;
|
||||
- (CGFloat)getFontSize;
|
||||
- (void)pushContext:(NSDictionary *)font;
|
||||
- (void)pushContext:(NSDictionary *)font deltaX:(NSArray<NSString *> *)deltaX deltaY:(NSArray<NSString *> *)deltaY positionX:(NSArray<NSString *> *)positionX positionY:(NSArray<NSString *> *)positionY;
|
||||
- (void)popContext;
|
||||
- (CTFontRef)getGlyphFont;
|
||||
- (CGPoint)getNextGlyphPoint:(CGPoint)offset glyphWidth:(CGFloat)glyphWidth;
|
||||
|
||||
@end
|
||||
@@ -1,205 +0,0 @@
|
||||
/**
|
||||
* 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 "RNSVGGlyphContext.h"
|
||||
#import "RNSVGPercentageConverter.h"
|
||||
#import <React/RCTFont.h>
|
||||
#import "RNSVGNode.h"
|
||||
|
||||
@implementation RNSVGGlyphContext
|
||||
{
|
||||
NSMutableArray<NSDictionary* > *_fontContext;
|
||||
NSMutableArray<NSValue* > *_locationContext;
|
||||
NSMutableArray<NSArray *> *_deltaXContext;
|
||||
NSMutableArray<NSArray *> *_deltaYContext;
|
||||
NSMutableArray<NSNumber *> *_xContext;
|
||||
CGPoint _currentLocation;
|
||||
CGFloat _width;
|
||||
CGFloat _height;
|
||||
CGFloat _fontSize;
|
||||
}
|
||||
|
||||
- (instancetype)initWithDimensions:(CGFloat)width height:(CGFloat)height
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_width = width;
|
||||
_height = height;
|
||||
_fontContext = [[NSMutableArray alloc] init];
|
||||
_locationContext = [[NSMutableArray alloc] init];
|
||||
_deltaXContext = [[NSMutableArray alloc] init];
|
||||
_deltaYContext = [[NSMutableArray alloc] init];
|
||||
_xContext = [[NSMutableArray alloc] init];
|
||||
_currentLocation = CGPointZero;
|
||||
_fontSize = DEFAULT_FONT_SIZE;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (CGFloat) getWidth
|
||||
{
|
||||
return _width;
|
||||
}
|
||||
|
||||
- (CGFloat) getHeight {
|
||||
return _height;
|
||||
}
|
||||
|
||||
- (CGFloat) getFontSize
|
||||
{
|
||||
return _fontSize;
|
||||
}
|
||||
|
||||
- (void)pushContext:(NSDictionary *)font
|
||||
{
|
||||
CGPoint location = _currentLocation;
|
||||
|
||||
[_locationContext addObject:[NSValue valueWithCGPoint:location]];
|
||||
[_fontContext addObject:font ? font : @{}];
|
||||
[_xContext addObject:[NSNumber numberWithFloat:location.x]];
|
||||
_currentLocation = location;
|
||||
}
|
||||
|
||||
- (void)pushContext:(NSDictionary *)font deltaX:(NSArray<NSString *> *)deltaX deltaY:(NSArray<NSString *> *)deltaY positionX:(NSArray<NSString *> *)positionX positionY:(NSArray<NSString *> *)positionY
|
||||
{
|
||||
CGPoint location = _currentLocation;
|
||||
|
||||
if (positionX) {
|
||||
location.x = [RNSVGPercentageConverter stringToFloat:[positionX firstObject] relative:_width offset:0];
|
||||
}
|
||||
|
||||
if (positionY) {
|
||||
location.y = [RNSVGPercentageConverter stringToFloat:[positionY firstObject] relative:_height offset:0];
|
||||
}
|
||||
|
||||
[_locationContext addObject:[NSValue valueWithCGPoint:location]];
|
||||
[_fontContext addObject:font ? font : @{}];
|
||||
[_deltaXContext addObject:deltaX ? deltaX : @[]];
|
||||
[_deltaYContext addObject:deltaY ? deltaY : @[]];
|
||||
[_xContext addObject:[NSNumber numberWithFloat:location.x]];
|
||||
_currentLocation = location;
|
||||
}
|
||||
|
||||
- (void)popContext
|
||||
{
|
||||
NSNumber *x = [_xContext lastObject];
|
||||
[_fontContext removeLastObject];
|
||||
[_locationContext removeLastObject];
|
||||
[_deltaXContext removeLastObject];
|
||||
[_deltaYContext removeLastObject];
|
||||
[_xContext removeLastObject];
|
||||
|
||||
if (_xContext.count) {
|
||||
[_xContext replaceObjectAtIndex:_xContext.count - 1 withObject:x];
|
||||
}
|
||||
|
||||
if (_locationContext.count) {
|
||||
_currentLocation = [[_locationContext lastObject] CGPointValue];
|
||||
_currentLocation.x = [x floatValue];
|
||||
[_locationContext replaceObjectAtIndex:_locationContext.count - 1
|
||||
withObject:[NSValue valueWithCGPoint:_currentLocation]];
|
||||
}
|
||||
}
|
||||
|
||||
- (CGPoint)getNextGlyphPoint:(CGPoint)offset glyphWidth:(CGFloat)glyphWidth
|
||||
{
|
||||
CGPoint currentLocation = _currentLocation;
|
||||
NSNumber *dx = [self getNextDelta:_deltaXContext];
|
||||
currentLocation.x += [dx floatValue];
|
||||
|
||||
NSNumber *dy = [self getNextDelta:_deltaYContext];
|
||||
currentLocation.y += [dy floatValue];
|
||||
|
||||
for (NSUInteger i = 0; i < _locationContext.count; i++) {
|
||||
CGPoint point = [[_locationContext objectAtIndex:i] CGPointValue];
|
||||
point.x += [dx floatValue];
|
||||
point.y += [dy floatValue];
|
||||
[_locationContext replaceObjectAtIndex:i withObject:[NSValue valueWithCGPoint:point]];
|
||||
}
|
||||
|
||||
_currentLocation = currentLocation;
|
||||
NSNumber *x = [NSNumber numberWithFloat:currentLocation.x + offset.x + glyphWidth];
|
||||
[_xContext replaceObjectAtIndex:_xContext.count - 1 withObject:x];
|
||||
return CGPointMake(currentLocation.x + offset.x, currentLocation.y + offset.y);
|
||||
}
|
||||
|
||||
- (NSNumber *)getNextDelta:(NSMutableArray *)deltaContext
|
||||
{
|
||||
NSNumber *value;
|
||||
NSUInteger index = deltaContext.count;
|
||||
for (NSArray *delta in [deltaContext reverseObjectEnumerator]) {
|
||||
index--;
|
||||
if (value == nil) {
|
||||
value = [delta firstObject];
|
||||
}
|
||||
|
||||
if (delta.count) {
|
||||
NSMutableArray *mutableDelta = [delta mutableCopy];
|
||||
[mutableDelta removeObjectAtIndex:0];
|
||||
[deltaContext replaceObjectAtIndex:index withObject:[mutableDelta copy]];
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
- (CTFontRef)getGlyphFont
|
||||
{
|
||||
NSString *fontFamily;
|
||||
NSNumber *fontSize;
|
||||
NSString *fontWeight;
|
||||
NSString *fontStyle;
|
||||
NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
|
||||
f.numberStyle = NSNumberFormatterDecimalStyle;
|
||||
|
||||
for (NSDictionary *font in [_fontContext reverseObjectEnumerator]) {
|
||||
if (!fontFamily) {
|
||||
fontFamily = font[@"fontFamily"];
|
||||
}
|
||||
|
||||
if (fontSize == nil) {
|
||||
fontSize = [f numberFromString:font[@"fontSize"]];
|
||||
}
|
||||
|
||||
if (!fontWeight) {
|
||||
fontWeight = font[@"fontWeight"];
|
||||
}
|
||||
if (!fontStyle) {
|
||||
fontStyle = font[@"fontStyle"];
|
||||
}
|
||||
|
||||
if (fontFamily && fontSize && fontWeight && fontStyle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL fontFamilyFound = NO;
|
||||
NSArray *supportedFontFamilyNames = [UIFont familyNames];
|
||||
|
||||
if ([supportedFontFamilyNames containsObject:fontFamily]) {
|
||||
fontFamilyFound = YES;
|
||||
} else {
|
||||
for (NSString *fontFamilyName in supportedFontFamilyNames) {
|
||||
if ([[UIFont fontNamesForFamilyName: fontFamilyName] containsObject:fontFamily]) {
|
||||
fontFamilyFound = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fontFamily = fontFamilyFound ? fontFamily : nil;
|
||||
|
||||
return (__bridge CTFontRef)[RCTFont updateFont:nil
|
||||
withFamily:fontFamily
|
||||
size:fontSize
|
||||
weight:fontWeight
|
||||
style:fontStyle
|
||||
variant:nil
|
||||
scaleMultiplier:1.0];
|
||||
}
|
||||
|
||||
@end
|
||||
+497
-456
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,5 @@
|
||||
- (void)releaseCachedPath;
|
||||
- (CGPathRef)getGroupPath:(CGContextRef)context;
|
||||
- (CTFontRef)getFontFromContext;
|
||||
- (CGPoint)getGlyphPointFromContext:(CGPoint)offset glyphWidth:(CGFloat)glyphWidth;
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,14 +10,12 @@
|
||||
#import "RNSVGTextPath.h"
|
||||
#import <React/RCTFont.h>
|
||||
#import <CoreText/CoreText.h>
|
||||
#import "RNSVGGlyphContext.h"
|
||||
#import "GlyphContext.h"
|
||||
|
||||
@implementation RNSVGText
|
||||
{
|
||||
RNSVGText *_textRoot;
|
||||
GlyphContext *_glyphContext;
|
||||
RNSVGGlyphContext *_RNSVGGlyphContext;
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
@@ -40,8 +38,6 @@
|
||||
{
|
||||
_glyphContext = [[GlyphContext alloc] initWithScale:1 width:[self getContextWidth]
|
||||
height:[self getContextHeight]];
|
||||
_RNSVGGlyphContext = [[RNSVGGlyphContext alloc] initWithDimensions:[self getContextWidth]
|
||||
height:[self getContextHeight]];
|
||||
}
|
||||
|
||||
// release the cached CGPathRef for RNSVGTSpan
|
||||
@@ -95,11 +91,6 @@
|
||||
return _textRoot;
|
||||
}
|
||||
|
||||
- (RNSVGGlyphContext *)getRNSVGGlyphContext
|
||||
{
|
||||
return _RNSVGGlyphContext;
|
||||
}
|
||||
|
||||
- (GlyphContext *)getGlyphContext
|
||||
{
|
||||
return _glyphContext;
|
||||
@@ -107,12 +98,6 @@
|
||||
|
||||
- (void)pushGlyphContext
|
||||
{
|
||||
/*
|
||||
[[[self getTextRoot] getRNSVGGlyphContext] pushContext:self.font
|
||||
deltaX:self.deltaX
|
||||
deltaY:self.deltaY
|
||||
positionX:self.positionX
|
||||
positionY:self.positionY];*/
|
||||
[[[self getTextRoot] getGlyphContext] pushContextwithRNSVGText:self
|
||||
reset:false
|
||||
font:self.font
|
||||
@@ -125,7 +110,6 @@
|
||||
|
||||
- (void)popGlyphContext
|
||||
{
|
||||
//[[[self getTextRoot] getRNSVGGlyphContext] popContext];
|
||||
[[[self getTextRoot] getGlyphContext] popContext];
|
||||
}
|
||||
|
||||
@@ -134,9 +118,4 @@
|
||||
return [[[self getTextRoot] getGlyphContext] getGlyphFont];
|
||||
}
|
||||
|
||||
- (CGPoint)getGlyphPointFromContext:(CGPoint)offset glyphWidth:(CGFloat)glyphWidth
|
||||
{
|
||||
return [[[self getTextRoot] getRNSVGGlyphContext] getNextGlyphPoint:(CGPoint)offset glyphWidth:glyphWidth];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreText/CoreText.h>
|
||||
#import "RNSVGText.h"
|
||||
#import "RNSVGBezierTransformer.h"
|
||||
|
||||
@interface RNSVGTextPath : RNSVGText
|
||||
|
||||
@@ -21,6 +20,5 @@
|
||||
@property (nonatomic, strong) NSString *startOffset;
|
||||
|
||||
- (RNSVGPath *)getPath;
|
||||
- (RNSVGBezierTransformer *)getBezierTransformer;
|
||||
|
||||
@end
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
|
||||
#import "RNSVGTextPath.h"
|
||||
#import "RNSVGBezierTransformer.h"
|
||||
|
||||
@implementation RNSVGTextPath
|
||||
|
||||
@@ -31,14 +30,6 @@
|
||||
return path;
|
||||
}
|
||||
|
||||
- (RNSVGBezierTransformer *)getBezierTransformer
|
||||
{
|
||||
RNSVGPath *path = [self getPath];
|
||||
CGFloat startOffset = [self relativeOnWidth:self.startOffset];
|
||||
return [[RNSVGBezierTransformer alloc] initWithBezierCurvesAndStartOffset:[path getBezierCurves]
|
||||
startOffset:startOffset];
|
||||
}
|
||||
|
||||
- (CGPathRef)getPath:(CGContextRef)context
|
||||
{
|
||||
return [self getGroupPath:context];
|
||||
|
||||
@@ -27,5 +27,9 @@ RCT_EXPORT_VIEW_PROPERTY(positionX, NSArray<NSString *>)
|
||||
RCT_EXPORT_VIEW_PROPERTY(positionY, NSArray<NSString *>)
|
||||
RCT_EXPORT_VIEW_PROPERTY(rotate, NSArray<NSString *>)
|
||||
RCT_EXPORT_VIEW_PROPERTY(font, NSDictionary)
|
||||
RCT_EXPORT_VIEW_PROPERTY(textLength, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(baselineShift, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(lengthAdjust, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(alignmentBaseline, NSString)
|
||||
|
||||
@end
|
||||
|
||||
@@ -20,6 +20,10 @@ RCT_EXPORT_MODULE()
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(href, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(side, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(method, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(midLine, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(spacing, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(startOffset, NSString)
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user