Skip to content

Commit

Permalink
feat(ios): implement getTotalLength and getPointAtLength
Browse files Browse the repository at this point in the history
  • Loading branch information
msand committed Oct 3, 2019
1 parent 203e53b commit 78c4f20
Show file tree
Hide file tree
Showing 8 changed files with 320 additions and 265 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ public void run() {
} else {
successCallback.invoke(false);
}
return;
} else {
float scale = svg.mScale;
src[0] *= scale;
Expand Down
8 changes: 8 additions & 0 deletions ios/RNSVG.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@
947F38102148119A00677F2A /* RNSVGMaskManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 947F380E2148119A00677F2A /* RNSVGMaskManager.m */; };
9482DEFA23460EC800FC486E /* RNSVGContextBrush.m in Sources */ = {isa = PBXBuildFile; fileRef = 9482DEF823460EC700FC486E /* RNSVGContextBrush.m */; };
9482DEFB23460EC800FC486E /* RNSVGContextBrush.m in Sources */ = {isa = PBXBuildFile; fileRef = 9482DEF823460EC700FC486E /* RNSVGContextBrush.m */; };
9482DF02234680A200FC486E /* RNSVGPathMeasure.m in Sources */ = {isa = PBXBuildFile; fileRef = 9482DF00234680A200FC486E /* RNSVGPathMeasure.m */; };
9482DF03234680A200FC486E /* RNSVGPathMeasure.m in Sources */ = {isa = PBXBuildFile; fileRef = 9482DF00234680A200FC486E /* RNSVGPathMeasure.m */; };
9494C4D81F473BA700D5BCFD /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9494C4D71F473BA700D5BCFD /* QuartzCore.framework */; };
9494C4DA1F473BCB00D5BCFD /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9494C4D91F473BCB00D5BCFD /* CoreText.framework */; };
9494C4DC1F473BD900D5BCFD /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9494C4DB1F473BD900D5BCFD /* CoreGraphics.framework */; };
Expand Down Expand Up @@ -261,6 +263,8 @@
947F380E2148119A00677F2A /* RNSVGMaskManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGMaskManager.m; sourceTree = "<group>"; };
9482DEF823460EC700FC486E /* RNSVGContextBrush.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGContextBrush.m; sourceTree = "<group>"; };
9482DEF923460EC800FC486E /* RNSVGContextBrush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGContextBrush.h; sourceTree = "<group>"; };
9482DF00234680A200FC486E /* RNSVGPathMeasure.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGPathMeasure.m; path = Utils/RNSVGPathMeasure.m; sourceTree = "<group>"; };
9482DF01234680A200FC486E /* RNSVGPathMeasure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGPathMeasure.h; path = Utils/RNSVGPathMeasure.h; sourceTree = "<group>"; };
9494C4D71F473BA700D5BCFD /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
9494C4D91F473BCB00D5BCFD /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
9494C4DB1F473BD900D5BCFD /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -482,6 +486,8 @@
1039D29A1CE7212C001E90A8 /* Utils */ = {
isa = PBXGroup;
children = (
9482DF01234680A200FC486E /* RNSVGPathMeasure.h */,
9482DF00234680A200FC486E /* RNSVGPathMeasure.m */,
94A178FD2344097B00693CB3 /* RNSVGMarkerPosition.h */,
94A178FE2344097B00693CB3 /* RNSVGMarkerPosition.m */,
94696EE92235A7F200C1D558 /* RNSVGVectorEffect.h */,
Expand Down Expand Up @@ -608,6 +614,7 @@
9482DEFA23460EC800FC486E /* RNSVGContextBrush.m in Sources */,
0CF68B071AF0549300FF9E5C /* RNSVGRenderable.m in Sources */,
1039D2891CE71EB7001E90A8 /* RNSVGGroup.m in Sources */,
9482DF02234680A200FC486E /* RNSVGPathMeasure.m in Sources */,
10ED4A9E1CF0656A0078BC02 /* RNSVGClipPathManager.m in Sources */,
10BEC1C61D3F7BD300FDCB19 /* RNSVGPainter.m in Sources */,
10ED4AA21CF078830078BC02 /* RNSVGNode.m in Sources */,
Expand Down Expand Up @@ -674,6 +681,7 @@
9482DEFB23460EC800FC486E /* RNSVGContextBrush.m in Sources */,
A361E77D1EB0C33D00646005 /* RNSVGGroup.m in Sources */,
A361E77E1EB0C33D00646005 /* RNSVGClipPathManager.m in Sources */,
9482DF03234680A200FC486E /* RNSVGPathMeasure.m in Sources */,
A361E77F1EB0C33D00646005 /* RNSVGPainter.m in Sources */,
A361E7801EB0C33D00646005 /* RNSVGNode.m in Sources */,
A361E7811EB0C33D00646005 /* RNSVGClipPath.m in Sources */,
Expand Down
67 changes: 15 additions & 52 deletions ios/Text/RNSVGTSpan.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#import "RNSVGText.h"
#import "RNSVGTextPath.h"
#import "RNSVGTextProperties.h"
#import "RNSVGPathMeasure.h"
#import "RNSVGFontData.h"

static NSCharacterSet *RNSVGTSpan_separators = nil;
Expand Down Expand Up @@ -38,18 +39,14 @@ - (void)drawTextInRect:(CGRect) rect
@implementation RNSVGTSpan
{
CGFloat startOffset;
CGFloat _pathLength;
RNSVGTextPath *textPath;
NSArray *lengths;
NSArray *lines;
NSUInteger lineCount;
BOOL isClosed;
NSMutableArray *emoji;
NSMutableArray *emojiTransform;
CGFloat cachedAdvance;
CTFontRef fontRef;
CGFloat firstX;
CGFloat firstY;
RNSVGPathMeasure *measure;
}

- (id)init
Expand All @@ -62,6 +59,7 @@ - (id)init

emoji = [NSMutableArray arrayWithCapacity:0];
emojiTransform = [NSMutableArray arrayWithCapacity:0];
measure = [[RNSVGPathMeasure alloc]init];

return self;
}
Expand Down Expand Up @@ -476,7 +474,7 @@ vertical alternates (OpenType feature: vert) must be enabled.

int side = 1;
CGFloat startOfRendering = 0;
CGFloat endOfRendering = _pathLength;
CGFloat endOfRendering = measure.pathLength;
CGFloat fontSize = [gc getFontSize];
//bool sharpMidLine = false;
if (hasTextPath) {
Expand Down Expand Up @@ -541,13 +539,13 @@ For the start (end) value, the text is rendered from the start (end) of the line
the path is reached.
*/
CGFloat absoluteStartOffset = [RNSVGPropHelper fromRelative:textPath.startOffset
relative:_pathLength
relative:measure.pathLength
fontSize:fontSize];
offset += absoluteStartOffset;
if (isClosed) {
CGFloat halfPathDistance = _pathLength / 2;
if (measure.isClosed) {
CGFloat halfPathDistance = measure.pathLength / 2;
startOfRendering = absoluteStartOffset + (textAnchor == RNSVGTextAnchorMiddle ? -halfPathDistance : 0);
endOfRendering = startOfRendering + _pathLength;
endOfRendering = startOfRendering + measure.pathLength;
}
/*
RNSVGTextPathSpacing spacing = textPath.getSpacing();
Expand Down Expand Up @@ -958,39 +956,10 @@ A negative value is an error (see Error processing).
continue;
}

// Investigation suggests binary search is faster at lineCount >= 16
// https://gist.github.com/msand/4c7993319425f9d7933be58ad9ada1a4
NSUInteger i = lineCount < 16 ?
[lengths
indexOfObjectPassingTest:^(NSNumber* length, NSUInteger index, BOOL * _Nonnull stop) {
BOOL contains = midPoint <= [length doubleValue];
return contains;
}]
:
[lengths
indexOfObject:[NSNumber numberWithDouble:midPoint]
inSortedRange:NSMakeRange(0, lineCount)
options:NSBinarySearchingInsertionIndex
usingComparator:^(NSNumber* obj1, NSNumber* obj2) {
return [obj1 compare:obj2];
}];

CGFloat totalLength = (CGFloat)[lengths[i] doubleValue];
CGFloat prevLength = i == 0 ? 0 : (CGFloat)[lengths[i - 1] doubleValue];

CGFloat length = totalLength - prevLength;
CGFloat percent = (midPoint - prevLength) / length;

NSArray * points = [lines objectAtIndex: i];
CGPoint p1 = [[points objectAtIndex: 0] CGPointValue];
CGPoint p2 = [[points objectAtIndex: 1] CGPointValue];

CGFloat ldx = p2.x - p1.x;
CGFloat ldy = p2.y - p1.y;
CGFloat angle = atan2(ldy, ldx);

CGFloat px = p1.x + ldx * percent;
CGFloat py = p1.y + ldy * percent;
CGFloat angle;
CGFloat px;
CGFloat py;
[measure getPosAndTan:&angle midPoint:midPoint px:&px py:&py];

transform = CGAffineTransformConcat(CGAffineTransformMakeTranslation(px, py), transform);
transform = CGAffineTransformConcat(CGAffineTransformMakeRotation(angle + r), transform);
Expand Down Expand Up @@ -1061,24 +1030,18 @@ + (CGFloat)getTextAnchorOffset:(RNSVGTextAnchor)textAnchor width:(CGFloat) width

- (void)setupTextPath:(CGContextRef)context
{
lines = nil;
lengths = nil;
textPath = nil;
RNSVGText *parent = (RNSVGText*)[self superview];

while (parent) {
if ([parent class] == [RNSVGTextPath class]) {
textPath = (RNSVGTextPath*) parent;
[textPath getPathLength:&_pathLength
lineCount:&lineCount
lengths:&lengths
lines:&lines
isClosed:&isClosed];
RNSVGNode *template = [self.svgView getDefinedTemplate:textPath.href];
CGPathRef path = [template getPath:nil];
[measure extractPathData:path];
break;
} else if (![parent isKindOfClass:[RNSVGText class]]) {
break;
}

parent = (RNSVGText*)[parent superview];
}
}
Expand Down
3 changes: 0 additions & 3 deletions ios/Text/RNSVGTextPath.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,4 @@
@property (nonatomic, strong) NSString *spacing;
@property (nonatomic, strong) RNSVGLength *startOffset;

- (void)getPathLength:(CGFloat*)length lineCount:(NSUInteger*)lineCount lengths:(NSArray* __strong *)lengths lines:(NSArray* __strong *)lines isClosed:(BOOL*)isClosed;


@end
Loading

0 comments on commit 78c4f20

Please sign in to comment.