mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-05-30 13:38:30 +00:00
BezierPath => BezierTransformer
This commit is contained in:
@@ -9,12 +9,12 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface RNSVGBezierPath : NSObject
|
||||
@interface RNSVGBezierTransformer : NSObject
|
||||
|
||||
+ (BOOL) hasReachedEnd:(CGAffineTransform)transform;
|
||||
+ (BOOL) hasReachedStart:(CGAffineTransform) transform;
|
||||
|
||||
- (instancetype)initWithBezierCurvesAndStartOffset:(NSArray<NSArray *> *)bezierCurves startOffset:(CGFloat)startOffset;
|
||||
- (CGAffineTransform)transformAtDistance:(CGFloat)distance;
|
||||
- (CGAffineTransform)getTransformAtDistance:(CGFloat)distance;
|
||||
|
||||
@end
|
||||
@@ -10,11 +10,9 @@
|
||||
* based on CurvyText by iosptl: https://github.com/iosptl/ios7ptl/blob/master/ch21-Text/CurvyText/CurvyText/CurvyTextView.m
|
||||
*/
|
||||
|
||||
#import "RNSVGBezierPath.h"
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#import <CoreText/CoreText.h>
|
||||
#import "RNSVGBezierTransformer.h"
|
||||
|
||||
@implementation RNSVGBezierPath
|
||||
@implementation RNSVGBezierTransformer
|
||||
{
|
||||
NSArray<NSArray *> *_bezierCurves;
|
||||
int _currentBezierIndex;
|
||||
@@ -123,7 +121,7 @@ static CGFloat calculateDistance(CGPoint a, CGPoint b) {
|
||||
}
|
||||
|
||||
|
||||
- (CGAffineTransform)transformAtDistance:(CGFloat)distance
|
||||
- (CGAffineTransform)getTransformAtDistance:(CGFloat)distance
|
||||
{
|
||||
distance += _startOffset;
|
||||
if (_reachedEnd) {
|
||||
@@ -150,7 +148,7 @@ static CGFloat calculateDistance(CGPoint a, CGPoint b) {
|
||||
_lastPoint = _P0 = _P3;
|
||||
_lastRecord += _lastDistance;
|
||||
[self setControlPoints];
|
||||
return [self transformAtDistance:distance - _startOffset];
|
||||
return [self getTransformAtDistance:distance - _startOffset];
|
||||
}
|
||||
}
|
||||
|
||||
+34
-34
@@ -8,13 +8,13 @@
|
||||
|
||||
|
||||
#import "RNSVGTSpan.h"
|
||||
#import "RNSVGBezierPath.h"
|
||||
#import "RNSVGBezierTransformer.h"
|
||||
#import "RNSVGText.h"
|
||||
#import "RNSVGTextPath.h"
|
||||
|
||||
@implementation RNSVGTSpan
|
||||
{
|
||||
RNSVGBezierPath *_bezierPath;
|
||||
RNSVGBezierTransformer *_bezierTransformer;
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
@@ -33,32 +33,32 @@
|
||||
return [self getGroupPath:context];
|
||||
}
|
||||
[self setContextBoundingBox:CGContextGetClipBoundingBox(context)];
|
||||
|
||||
|
||||
[self initialTextPath];
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
|
||||
|
||||
if ([self.content isEqualToString:@""]) {
|
||||
RNSVGGlyphPoint computedPoint = [self getComputedGlyphPoint:0 glyphOffset:CGPointZero];
|
||||
[self getTextRoot].lastX = computedPoint.x;
|
||||
[self getTextRoot].lastY = computedPoint.y;
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
CTFontRef font = [self getComputedFont];
|
||||
// Create a dictionary for this font
|
||||
CFDictionaryRef attributes = (__bridge CFDictionaryRef)@{
|
||||
(NSString *)kCTFontAttributeName: (__bridge id)font,
|
||||
(NSString *)kCTForegroundColorFromContextAttributeName: @YES
|
||||
};
|
||||
|
||||
|
||||
CFStringRef string = (__bridge CFStringRef)self.content;
|
||||
CFAttributedStringRef attrString = CFAttributedStringCreate(kCFAllocatorDefault, string, attributes);
|
||||
CTLineRef line = CTLineCreateWithAttributedString(attrString);
|
||||
|
||||
|
||||
CGMutablePathRef linePath = [self getLinePath:line];
|
||||
CGAffineTransform offset = CGAffineTransformMakeTranslation(0, _bezierPath ? 0 : CTFontGetSize(font) * 1.1);
|
||||
CGAffineTransform offset = CGAffineTransformMakeTranslation(0, _bezierTransformer ? 0 : CTFontGetSize(font) * 1.1);
|
||||
CGPathAddPath(path, &offset, linePath);
|
||||
|
||||
|
||||
// clean up
|
||||
CFRelease(attrString);
|
||||
CFRelease(line);
|
||||
@@ -71,81 +71,81 @@
|
||||
{
|
||||
CGAffineTransform upsideDown = CGAffineTransformMakeScale(1.0, -1.0);
|
||||
CGMutablePathRef path = CGPathCreateMutable();
|
||||
|
||||
|
||||
CFArrayRef glyphRuns = CTLineGetGlyphRuns(line);
|
||||
CTRunRef run = CFArrayGetValueAtIndex(glyphRuns, 0);
|
||||
|
||||
|
||||
CFIndex runGlyphCount = CTRunGetGlyphCount(run);
|
||||
CGPoint positions[runGlyphCount];
|
||||
CGGlyph glyphs[runGlyphCount];
|
||||
|
||||
|
||||
// Grab the glyphs, positions, and font
|
||||
CTRunGetPositions(run, CFRangeMake(0, 0), positions);
|
||||
CTRunGetGlyphs(run, CFRangeMake(0, 0), glyphs);
|
||||
CFDictionaryRef attributes = CTRunGetAttributes(run);
|
||||
|
||||
|
||||
CTFontRef runFont = CFDictionaryGetValue(attributes, kCTFontAttributeName);
|
||||
|
||||
|
||||
CGFloat lineStartX;
|
||||
RNSVGGlyphPoint computedPoint;
|
||||
for(CFIndex i = 0; i < runGlyphCount; i++) {
|
||||
computedPoint = [self getComputedGlyphPoint:i glyphOffset:positions[i]];
|
||||
|
||||
|
||||
if (!i) {
|
||||
lineStartX = computedPoint.x;
|
||||
}
|
||||
|
||||
|
||||
CGPathRef letter = CTFontCreatePathForGlyph(runFont, glyphs[i], nil);
|
||||
|
||||
|
||||
CGAffineTransform textPathTransform = [self getTextPathTransform:computedPoint.x];
|
||||
|
||||
if ([RNSVGBezierPath hasReachedEnd:textPathTransform]) {
|
||||
|
||||
if ([RNSVGBezierTransformer hasReachedEnd:textPathTransform]) {
|
||||
break;
|
||||
} else if ([RNSVGBezierPath hasReachedStart:textPathTransform]) {
|
||||
} else if ([RNSVGBezierTransformer hasReachedStart:textPathTransform]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
CGAffineTransform transform;
|
||||
|
||||
if (_bezierPath) {
|
||||
|
||||
if (_bezierTransformer) {
|
||||
textPathTransform = CGAffineTransformConcat(CGAffineTransformMakeTranslation(0, computedPoint.y), textPathTransform);
|
||||
transform = CGAffineTransformScale(textPathTransform, 1.0, -1.0);
|
||||
} else {
|
||||
transform = CGAffineTransformTranslate(upsideDown, computedPoint.x, -computedPoint.y);
|
||||
}
|
||||
|
||||
|
||||
CGPathAddPath(path, &transform, letter);
|
||||
CGPathRelease(letter);
|
||||
}
|
||||
|
||||
|
||||
[self getTextRoot].lastX = computedPoint.x;
|
||||
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
- (void)initialTextPath
|
||||
{
|
||||
__block RNSVGBezierPath *bezierPath;
|
||||
__block RNSVGBezierTransformer *bezierTransformer;
|
||||
[self traverseTextSuperviews:^(__kindof RNSVGText *node) {
|
||||
if ([node class] == [RNSVGTextPath class]) {
|
||||
RNSVGTextPath *textPath = node;
|
||||
bezierPath = [node getBezierPath];
|
||||
bezierTransformer = [node getBezierTransformer];
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}];
|
||||
|
||||
_bezierPath = bezierPath;
|
||||
|
||||
_bezierTransformer = bezierTransformer;
|
||||
}
|
||||
|
||||
- (CGAffineTransform)getTextPathTransform:(CGFloat)distance
|
||||
{
|
||||
if (_bezierPath) {
|
||||
return [_bezierPath transformAtDistance:distance];
|
||||
if (_bezierTransformer) {
|
||||
return [_bezierTransformer getTransformAtDistance:distance];
|
||||
}
|
||||
|
||||
|
||||
return CGAffineTransformIdentity;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreText/CoreText.h>
|
||||
#import "RNSVGText.h"
|
||||
#import "RNSVGBezierPath.h"
|
||||
#import "RNSVGBezierTransformer.h"
|
||||
|
||||
@interface RNSVGTextPath : RNSVGText
|
||||
|
||||
@property (nonatomic, strong) NSString *href;
|
||||
@property (nonatomic, strong) NSString *startOffset;
|
||||
|
||||
- (RNSVGBezierPath *)getBezierPath;
|
||||
- (RNSVGBezierTransformer *)getBezierTransformer;
|
||||
|
||||
@end
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
|
||||
#import "RNSVGTextPath.h"
|
||||
#import "RNSVGBezierPath.h"
|
||||
#import "RNSVGBezierTransformer.h"
|
||||
|
||||
@implementation RNSVGTextPath
|
||||
|
||||
@@ -23,19 +23,20 @@
|
||||
return [self getGroupPath:context];
|
||||
}
|
||||
|
||||
- (RNSVGBezierPath *)getBezierPath
|
||||
- (RNSVGBezierTransformer *)getBezierTransformer
|
||||
{
|
||||
RNSVGSvgView *svg = [self getSvgView];
|
||||
RNSVGNode *template = [svg getDefinedTemplate:self.href];
|
||||
|
||||
|
||||
if ([template class] != [RNSVGPath class]) {
|
||||
// warning about this.
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
RNSVGPath *path = template;
|
||||
CGFloat startOffset = [self getWidthRelatedValue:self.startOffset];
|
||||
return [[RNSVGBezierPath alloc] initWithBezierCurvesAndStartOffset:[path getBezierCurves] startOffset:startOffset];
|
||||
return [[RNSVGBezierTransformer alloc] initWithBezierCurvesAndStartOffset:[path getBezierCurves]
|
||||
startOffset:startOffset];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user