mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-09 09:27:20 +00:00
Refactor Text related elements
This commit is contained in:
@@ -54,6 +54,7 @@
|
|||||||
7F08CEA01E23479700650F83 /* RNSVGTextPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F08CE9D1E23479700650F83 /* RNSVGTextPath.m */; };
|
7F08CEA01E23479700650F83 /* RNSVGTextPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F08CE9D1E23479700650F83 /* RNSVGTextPath.m */; };
|
||||||
7F08CEA11E23479700650F83 /* RNSVGTSpan.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F08CE9F1E23479700650F83 /* RNSVGTSpan.m */; };
|
7F08CEA11E23479700650F83 /* RNSVGTSpan.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F08CE9F1E23479700650F83 /* RNSVGTSpan.m */; };
|
||||||
7F9CDAFA1E1F809C00E0C805 /* RNSVGPathParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F9CDAF91E1F809C00E0C805 /* RNSVGPathParser.m */; };
|
7F9CDAFA1E1F809C00E0C805 /* RNSVGPathParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F9CDAF91E1F809C00E0C805 /* RNSVGPathParser.m */; };
|
||||||
|
7FFC4EA41E24E5AD00AD5BE5 /* RNSVGGlyphContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FFC4EA31E24E5AD00AD5BE5 /* RNSVGGlyphContext.m */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
@@ -167,10 +168,11 @@
|
|||||||
7F08CE9D1E23479700650F83 /* RNSVGTextPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGTextPath.m; path = Text/RNSVGTextPath.m; sourceTree = "<group>"; };
|
7F08CE9D1E23479700650F83 /* RNSVGTextPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGTextPath.m; path = Text/RNSVGTextPath.m; sourceTree = "<group>"; };
|
||||||
7F08CE9E1E23479700650F83 /* RNSVGTSpan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGTSpan.h; path = Text/RNSVGTSpan.h; sourceTree = "<group>"; };
|
7F08CE9E1E23479700650F83 /* RNSVGTSpan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGTSpan.h; path = Text/RNSVGTSpan.h; sourceTree = "<group>"; };
|
||||||
7F08CE9F1E23479700650F83 /* RNSVGTSpan.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGTSpan.m; path = Text/RNSVGTSpan.m; sourceTree = "<group>"; };
|
7F08CE9F1E23479700650F83 /* RNSVGTSpan.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGTSpan.m; path = Text/RNSVGTSpan.m; sourceTree = "<group>"; };
|
||||||
7F08CEA21E23481F00650F83 /* RNSVGGlyphPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGGlyphPoint.h; path = Utils/RNSVGGlyphPoint.h; sourceTree = "<group>"; };
|
|
||||||
7F08CEA31E23481F00650F83 /* RNSVGTextAnchor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGTextAnchor.h; path = Utils/RNSVGTextAnchor.h; sourceTree = "<group>"; };
|
7F08CEA31E23481F00650F83 /* RNSVGTextAnchor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGTextAnchor.h; path = Utils/RNSVGTextAnchor.h; sourceTree = "<group>"; };
|
||||||
7F9CDAF81E1F809C00E0C805 /* RNSVGPathParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGPathParser.h; path = Utils/RNSVGPathParser.h; sourceTree = "<group>"; };
|
7F9CDAF81E1F809C00E0C805 /* RNSVGPathParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGPathParser.h; path = Utils/RNSVGPathParser.h; sourceTree = "<group>"; };
|
||||||
7F9CDAF91E1F809C00E0C805 /* RNSVGPathParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGPathParser.m; path = Utils/RNSVGPathParser.m; sourceTree = "<group>"; };
|
7F9CDAF91E1F809C00E0C805 /* RNSVGPathParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGPathParser.m; path = Utils/RNSVGPathParser.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>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@@ -293,6 +295,8 @@
|
|||||||
1039D27F1CE71D9B001E90A8 /* Text */ = {
|
1039D27F1CE71D9B001E90A8 /* Text */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
7FFC4EA21E24E52500AD5BE5 /* RNSVGGlyphContext.h */,
|
||||||
|
7FFC4EA31E24E5AD00AD5BE5 /* RNSVGGlyphContext.m */,
|
||||||
7F08CE9C1E23479700650F83 /* RNSVGTextPath.h */,
|
7F08CE9C1E23479700650F83 /* RNSVGTextPath.h */,
|
||||||
7F08CE9D1E23479700650F83 /* RNSVGTextPath.m */,
|
7F08CE9D1E23479700650F83 /* RNSVGTextPath.m */,
|
||||||
7F08CE9E1E23479700650F83 /* RNSVGTSpan.h */,
|
7F08CE9E1E23479700650F83 /* RNSVGTSpan.h */,
|
||||||
@@ -333,7 +337,6 @@
|
|||||||
1039D29A1CE7212C001E90A8 /* Utils */ = {
|
1039D29A1CE7212C001E90A8 /* Utils */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
7F08CEA21E23481F00650F83 /* RNSVGGlyphPoint.h */,
|
|
||||||
7F08CEA31E23481F00650F83 /* RNSVGTextAnchor.h */,
|
7F08CEA31E23481F00650F83 /* RNSVGTextAnchor.h */,
|
||||||
1039D29E1CE72177001E90A8 /* RNSVGCGFloatArray.h */,
|
1039D29E1CE72177001E90A8 /* RNSVGCGFloatArray.h */,
|
||||||
10ABC7381D43982B006CCF6E /* RNSVGVBMOS.h */,
|
10ABC7381D43982B006CCF6E /* RNSVGVBMOS.h */,
|
||||||
@@ -410,6 +413,7 @@
|
|||||||
10BA0D341CE74E3100887C2B /* RNSVGCircleManager.m in Sources */,
|
10BA0D341CE74E3100887C2B /* RNSVGCircleManager.m in Sources */,
|
||||||
10BEC1BC1D3F66F500FDCB19 /* RNSVGLinearGradient.m in Sources */,
|
10BEC1BC1D3F66F500FDCB19 /* RNSVGLinearGradient.m in Sources */,
|
||||||
1039D2B01CE72F27001E90A8 /* RNSVGPercentageConverter.m in Sources */,
|
1039D2B01CE72F27001E90A8 /* RNSVGPercentageConverter.m in Sources */,
|
||||||
|
7FFC4EA41E24E5AD00AD5BE5 /* RNSVGGlyphContext.m in Sources */,
|
||||||
10BA0D491CE74E3D00887C2B /* RNSVGEllipse.m in Sources */,
|
10BA0D491CE74E3D00887C2B /* RNSVGEllipse.m in Sources */,
|
||||||
10ABC7331D435915006CCF6E /* RNSVGViewBoxManager.m in Sources */,
|
10ABC7331D435915006CCF6E /* RNSVGViewBoxManager.m in Sources */,
|
||||||
1039D28B1CE71EB7001E90A8 /* RNSVGPath.m in Sources */,
|
1039D28B1CE71EB7001E90A8 /* RNSVGPath.m in Sources */,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#import "RNSVGCGFloatArray.h"
|
#import "RNSVGCGFloatArray.h"
|
||||||
#import "RNSVGCGFCRule.h"
|
#import "RNSVGCGFCRule.h"
|
||||||
#import "RNSVGNode.h"
|
#import "RNSVGNode.h"
|
||||||
|
#import "RNSVGPercentageConverter.h"
|
||||||
|
|
||||||
@interface RNSVGRenderable : RNSVGNode
|
@interface RNSVGRenderable : RNSVGNode
|
||||||
|
|
||||||
@@ -36,5 +37,7 @@
|
|||||||
- (CGRect)getLayoutBoundingBox;
|
- (CGRect)getLayoutBoundingBox;
|
||||||
- (CGFloat)getWidthRelatedValue:(NSString *)string;
|
- (CGFloat)getWidthRelatedValue:(NSString *)string;
|
||||||
- (CGFloat)getHeightRelatedValue:(NSString *)string;
|
- (CGFloat)getHeightRelatedValue:(NSString *)string;
|
||||||
|
- (RNSVGPercentageConverter *)getWidthConverter;
|
||||||
|
- (RNSVGPercentageConverter *)getHeightConverter;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
+10
-1
@@ -7,7 +7,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import "RNSVGRenderable.h"
|
#import "RNSVGRenderable.h"
|
||||||
#import "RNSVGPercentageConverter.h"
|
|
||||||
|
|
||||||
@implementation RNSVGRenderable
|
@implementation RNSVGRenderable
|
||||||
{
|
{
|
||||||
@@ -308,6 +307,16 @@
|
|||||||
offset:0];
|
offset:0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (RNSVGPercentageConverter *)getWidthConverter
|
||||||
|
{
|
||||||
|
return _widthConverter;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (RNSVGPercentageConverter *)getHeightConverter
|
||||||
|
{
|
||||||
|
return _heightConverter;
|
||||||
|
}
|
||||||
|
|
||||||
- (CGRect)getContextBoundingBox
|
- (CGRect)getContextBoundingBox
|
||||||
{
|
{
|
||||||
return _contextBoundingBox;
|
return _contextBoundingBox;
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* 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)initWithConverters:(RNSVGPercentageConverter *)widthConverter heightConverter:(RNSVGPercentageConverter *)heightConverter;
|
||||||
|
- (void)pushContext:(NSDictionary *)font deltaX:(NSArray<NSNumber *> *)deltaX deltaY:(NSArray<NSNumber *> *)deltaY positionX:(NSString *)positionX positionY:(NSString *)positionY;
|
||||||
|
- (void)popContext;
|
||||||
|
- (CTFontRef)getGlyphFont;
|
||||||
|
- (CGPoint)getNextGlyphPoint:(CGPoint)offset glyphWidth:(CGFloat)glyphWidth;
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
/**
|
||||||
|
* 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 <React/RCTFont.h>
|
||||||
|
|
||||||
|
@implementation RNSVGGlyphContext
|
||||||
|
{
|
||||||
|
NSMutableArray<NSDictionary* > *_fontContext;
|
||||||
|
NSMutableArray<NSValue* > *_locationContext;
|
||||||
|
NSMutableArray<NSArray *> *_deltaXContext;
|
||||||
|
NSMutableArray<NSArray *> *_deltaYContext;
|
||||||
|
NSMutableArray<NSNumber *> *_xContext;
|
||||||
|
CGPoint _currentLocation;
|
||||||
|
RNSVGPercentageConverter *_widthConverter;
|
||||||
|
RNSVGPercentageConverter *_heightConverter;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithConverters:(RNSVGPercentageConverter *)widthConverter heightConverter:(RNSVGPercentageConverter *)heightConverter
|
||||||
|
{
|
||||||
|
if (self = [super init]) {
|
||||||
|
_widthConverter = widthConverter;
|
||||||
|
_heightConverter = heightConverter;
|
||||||
|
_fontContext = [[NSMutableArray alloc] init];
|
||||||
|
_locationContext = [[NSMutableArray alloc] init];
|
||||||
|
_deltaXContext = [[NSMutableArray alloc] init];
|
||||||
|
_deltaYContext = [[NSMutableArray alloc] init];
|
||||||
|
_xContext = [[NSMutableArray alloc] init];
|
||||||
|
_currentLocation = CGPointZero;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)pushContext:(NSDictionary *)font deltaX:(NSArray<NSNumber *> *)deltaX deltaY:(NSArray<NSNumber *> *)deltaY positionX:(NSString *)positionX positionY:(NSString *)positionY
|
||||||
|
{
|
||||||
|
CGPoint location = _currentLocation;
|
||||||
|
|
||||||
|
if (positionX) {
|
||||||
|
location.x = [_widthConverter stringToFloat:positionX];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (positionY) {
|
||||||
|
location.y = [_heightConverter stringToFloat:positionY];
|
||||||
|
}
|
||||||
|
|
||||||
|
[_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];
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
for (NSDictionary *font in [_fontContext reverseObjectEnumerator]) {
|
||||||
|
if (!fontFamily) {
|
||||||
|
fontFamily = font[@"fontFamily"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fontSize == nil) {
|
||||||
|
fontSize = 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
|
||||||
+57
-39
@@ -15,6 +15,7 @@
|
|||||||
@implementation RNSVGTSpan
|
@implementation RNSVGTSpan
|
||||||
{
|
{
|
||||||
RNSVGBezierTransformer *_bezierTransformer;
|
RNSVGBezierTransformer *_bezierTransformer;
|
||||||
|
CGPathRef _cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)renderLayerTo:(CGContextRef)context
|
- (void)renderLayerTo:(CGContextRef)context
|
||||||
@@ -27,31 +28,39 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)releaseCachedPath
|
||||||
|
{
|
||||||
|
CGPathRelease(_cache);
|
||||||
|
_cache = nil;
|
||||||
|
}
|
||||||
|
|
||||||
- (CGPathRef)getPath:(CGContextRef)context
|
- (CGPathRef)getPath:(CGContextRef)context
|
||||||
{
|
{
|
||||||
if (!self.content) {
|
if (_cache) {
|
||||||
return [self getGroupPath:context];
|
return _cache;
|
||||||
}
|
}
|
||||||
[self setContextBoundingBox:CGContextGetClipBoundingBox(context)];
|
|
||||||
|
NSString *text = self.content;
|
||||||
|
if (!text) {
|
||||||
|
return [super getPath:context];
|
||||||
|
}
|
||||||
|
|
||||||
[self initialTextPath];
|
[self initialTextPath];
|
||||||
|
[self setContextBoundingBox:CGContextGetClipBoundingBox(context)];
|
||||||
|
|
||||||
CGMutablePathRef path = CGPathCreateMutable();
|
CGMutablePathRef path = CGPathCreateMutable();
|
||||||
|
|
||||||
if ([self.content isEqualToString:@""]) {
|
// append spacing
|
||||||
RNSVGGlyphPoint computedPoint = [self getComputedGlyphPoint:0 glyphOffset:CGPointZero];
|
text = [text stringByAppendingString:@" "];
|
||||||
[self getTextRoot].lastX = computedPoint.x;
|
|
||||||
[self getTextRoot].lastY = computedPoint.y;
|
CTFontRef font = [self getFontFromContext];
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
CTFontRef font = [self getComputedFont];
|
|
||||||
// Create a dictionary for this font
|
// Create a dictionary for this font
|
||||||
CFDictionaryRef attributes = (__bridge CFDictionaryRef)@{
|
CFDictionaryRef attributes = (__bridge CFDictionaryRef)@{
|
||||||
(NSString *)kCTFontAttributeName: (__bridge id)font,
|
(NSString *)kCTFontAttributeName: (__bridge id)font,
|
||||||
(NSString *)kCTForegroundColorFromContextAttributeName: @YES
|
(NSString *)kCTForegroundColorFromContextAttributeName: @YES
|
||||||
};
|
};
|
||||||
|
|
||||||
CFStringRef string = (__bridge CFStringRef)self.content;
|
CFStringRef string = (__bridge CFStringRef)text;
|
||||||
CFAttributedStringRef attrString = CFAttributedStringCreate(kCFAllocatorDefault, string, attributes);
|
CFAttributedStringRef attrString = CFAttributedStringCreate(kCFAllocatorDefault, string, attributes);
|
||||||
CTLineRef line = CTLineCreateWithAttributedString(attrString);
|
CTLineRef line = CTLineCreateWithAttributedString(attrString);
|
||||||
|
|
||||||
@@ -63,17 +72,16 @@
|
|||||||
CFRelease(attrString);
|
CFRelease(attrString);
|
||||||
CFRelease(line);
|
CFRelease(line);
|
||||||
CGPathRelease(linePath);
|
CGPathRelease(linePath);
|
||||||
[self resetTextPathAttributes];
|
|
||||||
|
_cache = CGPathRetain(CGPathCreateCopy(path));
|
||||||
|
|
||||||
return (CGPathRef)CFAutorelease(path);
|
return (CGPathRef)CFAutorelease(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGMutablePathRef)getLinePath:(CTLineRef)line
|
- (CGMutablePathRef)getLinePath:(CTLineRef)line
|
||||||
{
|
{
|
||||||
CGAffineTransform upsideDown = CGAffineTransformMakeScale(1.0, -1.0);
|
[self pushGlyphContext];
|
||||||
CGMutablePathRef path = CGPathCreateMutable();
|
CTRunRef run = CFArrayGetValueAtIndex(CTLineGetGlyphRuns(line), 0);
|
||||||
|
|
||||||
CFArrayRef glyphRuns = CTLineGetGlyphRuns(line);
|
|
||||||
CTRunRef run = CFArrayGetValueAtIndex(glyphRuns, 0);
|
|
||||||
|
|
||||||
CFIndex runGlyphCount = CTRunGetGlyphCount(run);
|
CFIndex runGlyphCount = CTRunGetGlyphCount(run);
|
||||||
CGPoint positions[runGlyphCount];
|
CGPoint positions[runGlyphCount];
|
||||||
@@ -82,22 +90,17 @@
|
|||||||
// Grab the glyphs, positions, and font
|
// Grab the glyphs, positions, and font
|
||||||
CTRunGetPositions(run, CFRangeMake(0, 0), positions);
|
CTRunGetPositions(run, CFRangeMake(0, 0), positions);
|
||||||
CTRunGetGlyphs(run, CFRangeMake(0, 0), glyphs);
|
CTRunGetGlyphs(run, CFRangeMake(0, 0), glyphs);
|
||||||
CFDictionaryRef attributes = CTRunGetAttributes(run);
|
CTFontRef runFont = CFDictionaryGetValue(CTRunGetAttributes(run), kCTFontAttributeName);
|
||||||
|
|
||||||
CTFontRef runFont = CFDictionaryGetValue(attributes, kCTFontAttributeName);
|
CGPoint glyphPoint;
|
||||||
|
CGMutablePathRef path = CGPathCreateMutable();
|
||||||
CGFloat lineStartX;
|
|
||||||
RNSVGGlyphPoint computedPoint;
|
|
||||||
for(CFIndex i = 0; i < runGlyphCount; i++) {
|
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);
|
CGPathRef letter = CTFontCreatePathForGlyph(runFont, glyphs[i], nil);
|
||||||
|
|
||||||
CGAffineTransform textPathTransform = [self getTextPathTransform:computedPoint.x];
|
glyphPoint = [self getGlyphPointFromContext:positions[i] glyphWidth:CGPathGetBoundingBox(letter).size.width];
|
||||||
|
|
||||||
|
CGAffineTransform textPathTransform = [self getTextPathTransform:glyphPoint.x];
|
||||||
|
|
||||||
if ([RNSVGBezierTransformer hasReachedEnd:textPathTransform]) {
|
if ([RNSVGBezierTransformer hasReachedEnd:textPathTransform]) {
|
||||||
break;
|
break;
|
||||||
@@ -108,18 +111,17 @@
|
|||||||
CGAffineTransform transform;
|
CGAffineTransform transform;
|
||||||
|
|
||||||
if (_bezierTransformer) {
|
if (_bezierTransformer) {
|
||||||
textPathTransform = CGAffineTransformConcat(CGAffineTransformMakeTranslation(0, computedPoint.y), textPathTransform);
|
textPathTransform = CGAffineTransformConcat(CGAffineTransformMakeTranslation(0, glyphPoint.y), textPathTransform);
|
||||||
transform = CGAffineTransformScale(textPathTransform, 1.0, -1.0);
|
transform = CGAffineTransformScale(textPathTransform, 1.0, -1.0);
|
||||||
} else {
|
} else {
|
||||||
transform = CGAffineTransformTranslate(upsideDown, computedPoint.x, -computedPoint.y);
|
transform = CGAffineTransformTranslate(CGAffineTransformMakeScale(1.0, -1.0), glyphPoint.x, -glyphPoint.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
CGPathAddPath(path, &transform, letter);
|
CGPathAddPath(path, &transform, letter);
|
||||||
CGPathRelease(letter);
|
CGPathRelease(letter);
|
||||||
}
|
}
|
||||||
|
|
||||||
[self getTextRoot].lastX = computedPoint.x;
|
[self popGlyphContext];
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,6 +140,22 @@
|
|||||||
_bezierTransformer = bezierTransformer;
|
_bezierTransformer = bezierTransformer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)traverseTextSuperviews:(BOOL (^)(__kindof RNSVGText *node))block
|
||||||
|
{
|
||||||
|
RNSVGText *targetView = self;
|
||||||
|
BOOL result = block(self);
|
||||||
|
|
||||||
|
while (targetView && [targetView class] != [RNSVGText class] && result) {
|
||||||
|
if (![targetView isKindOfClass:[RNSVGText class]]) {
|
||||||
|
//todo: throw exception here
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
targetView = [targetView superview];
|
||||||
|
result = block(targetView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (CGAffineTransform)getTextPathTransform:(CGFloat)distance
|
- (CGAffineTransform)getTextPathTransform:(CGFloat)distance
|
||||||
{
|
{
|
||||||
if (_bezierTransformer) {
|
if (_bezierTransformer) {
|
||||||
|
|||||||
@@ -7,9 +7,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "RNSVGGlyphPoint.h"
|
|
||||||
#import "RNSVGGroup.h"
|
#import "RNSVGGroup.h"
|
||||||
#import "RNSVGTextAnchor.h"
|
#import "RNSVGTextAnchor.h"
|
||||||
|
#import "RNSVGGlyphContext.h"
|
||||||
|
|
||||||
@interface RNSVGText : RNSVGGroup
|
@interface RNSVGText : RNSVGGroup
|
||||||
|
|
||||||
@@ -24,11 +24,13 @@
|
|||||||
@property (nonatomic, assign) CGFloat lastY;
|
@property (nonatomic, assign) CGFloat lastY;
|
||||||
@property (nonatomic, assign) NSUInteger lastIndex;
|
@property (nonatomic, assign) NSUInteger lastIndex;
|
||||||
|
|
||||||
- (CTFontRef)getComputedFont;
|
|
||||||
- (RNSVGGlyphPoint)getComputedGlyphPoint:(NSUInteger *)index glyphOffset:(CGPoint)glyphOffset;
|
|
||||||
- (RNSVGText *)getTextRoot;
|
- (RNSVGText *)getTextRoot;
|
||||||
- (CGPathRef)getGroupPath:(CGContextRef)context;
|
- (void)releaseCachedPath;
|
||||||
- (void)resetTextPathAttributes;
|
|
||||||
- (void)traverseTextSuperviews:(BOOL (^)(__kindof RNSVGText *node))block;
|
- (RNSVGGlyphContext *)getGlyphContext;
|
||||||
|
- (void)pushGlyphContext;
|
||||||
|
- (void)popGlyphContext;
|
||||||
|
- (CTFontRef)getFontFromContext;
|
||||||
|
- (CGPoint)getGlyphPointFromContext:(CGPoint)offset glyphWidth:(CGFloat)glyphWidth;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
+72
-171
@@ -10,10 +10,12 @@
|
|||||||
#import "RNSVGTextPath.h"
|
#import "RNSVGTextPath.h"
|
||||||
#import <React/RCTFont.h>
|
#import <React/RCTFont.h>
|
||||||
#import <CoreText/CoreText.h>
|
#import <CoreText/CoreText.h>
|
||||||
|
#import "RNSVGGlyphContext.h"
|
||||||
|
|
||||||
@implementation RNSVGText
|
@implementation RNSVGText
|
||||||
{
|
{
|
||||||
RNSVGText *_textRoot;
|
RNSVGText *_textRoot;
|
||||||
|
RNSVGGlyphContext *_glyphContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setTextAnchor:(RNSVGTextAnchor)textAnchor
|
- (void)setTextAnchor:(RNSVGTextAnchor)textAnchor
|
||||||
@@ -24,206 +26,83 @@
|
|||||||
|
|
||||||
- (void)renderLayerTo:(CGContextRef)context
|
- (void)renderLayerTo:(CGContextRef)context
|
||||||
{
|
{
|
||||||
|
[self setContextBoundingBox:CGContextGetClipBoundingBox(context)];
|
||||||
|
_glyphContext = [[RNSVGGlyphContext alloc] initWithConverters:[self getWidthConverter]
|
||||||
|
heightConverter:[self getHeightConverter]];
|
||||||
|
|
||||||
[self clip:context];
|
[self clip:context];
|
||||||
CGContextSaveGState(context);
|
CGContextSaveGState(context);
|
||||||
CGAffineTransform transform = CGAffineTransformMakeTranslation([self getShift:context path:nil], 0);
|
CGAffineTransform transform = [self getAlignTransform:context];
|
||||||
CGContextConcatCTM(context, transform);
|
CGContextConcatCTM(context, transform);
|
||||||
[self renderGroupTo:context];
|
[self renderGroupTo:context];
|
||||||
[self resetTextPathAttributes];
|
[self releaseCachedPath];
|
||||||
CGContextRestoreGState(context);
|
CGContextRestoreGState(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)releaseCachedPath
|
||||||
|
{
|
||||||
|
[self traverseSubviews:^BOOL(__kindof RNSVGNode *node) {
|
||||||
|
RNSVGText *text = node;
|
||||||
|
[text releaseCachedPath];
|
||||||
|
return YES;
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
- (CGPathRef)getPath:(CGContextRef)context
|
- (CGPathRef)getPath:(CGContextRef)context
|
||||||
{
|
{
|
||||||
CGPathRef path = [self getGroupPath:context];
|
[self pushGlyphContext];
|
||||||
CGAffineTransform transform = CGAffineTransformMakeTranslation([self getShift:context path:path], 0);
|
|
||||||
CGPathRef transformedPath = CGPathCreateCopyByTransformingPath(path, &transform);
|
|
||||||
|
|
||||||
// check memory leaks here
|
|
||||||
//CGPathRelease(path);
|
|
||||||
return (CGPathRef)CFAutorelease(transformedPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CGPathRef)getGroupPath:(CGContextRef)context
|
|
||||||
{
|
|
||||||
CGPathRef groupPath = [super getPath:context];
|
CGPathRef groupPath = [super getPath:context];
|
||||||
[self resetTextPathAttributes];
|
[self popGlyphContext];
|
||||||
return groupPath;
|
|
||||||
|
CGAffineTransform transform = [self getAlignTransform:context path:groupPath];
|
||||||
|
CGPathRef transformedPath = CGPathCreateCopyByTransformingPath(groupPath, &transform);
|
||||||
|
|
||||||
|
return transformedPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGFloat)getShift:(CGContextRef)context path:(CGPathRef)path
|
- (void)renderGroupTo:(CGContextRef)context
|
||||||
|
{
|
||||||
|
[self pushGlyphContext];
|
||||||
|
[super renderGroupTo:context];
|
||||||
|
[self popGlyphContext];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGAffineTransform)getAlignTransform:(CGContextRef)context
|
||||||
|
{
|
||||||
|
return [self getAlignTransform:context path:[self getPath:context]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (CGAffineTransform)getAlignTransform:(CGContextRef)context path:(CGPathRef)path
|
||||||
{
|
{
|
||||||
if (path == nil) {
|
|
||||||
path = [self getGroupPath:context];
|
|
||||||
}
|
|
||||||
|
|
||||||
CGFloat width = CGRectGetWidth(CGPathGetBoundingBox(path));
|
CGFloat width = CGRectGetWidth(CGPathGetBoundingBox(path));
|
||||||
|
CGFloat x = 0;
|
||||||
|
|
||||||
switch ([self getComputedTextAnchor]) {
|
switch ([self getComputedTextAnchor]) {
|
||||||
case kRNSVGTextAnchorMiddle:
|
case kRNSVGTextAnchorMiddle:
|
||||||
return -width / 2;
|
x = -width / 2;
|
||||||
|
break;
|
||||||
case kRNSVGTextAnchorEnd:
|
case kRNSVGTextAnchorEnd:
|
||||||
return -width;
|
x = -width;
|
||||||
default:
|
break;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return CGAffineTransformMakeTranslation(x, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (RNSVGTextAnchor)getComputedTextAnchor
|
- (RNSVGTextAnchor)getComputedTextAnchor
|
||||||
{
|
{
|
||||||
RNSVGTextAnchor anchor = self.textAnchor;
|
RNSVGTextAnchor anchor = self.textAnchor;
|
||||||
if (self.subviews.count > 0) {
|
if (self.subviews.count > 0) {
|
||||||
RNSVGText *child = [self.subviews objectAtIndex:0];
|
RNSVGText *child = [self.subviews firstObject];
|
||||||
|
|
||||||
while (child.subviews.count && anchor == kRNSVGTextAnchorAuto) {
|
while (child.subviews.count && anchor == kRNSVGTextAnchorAuto) {
|
||||||
anchor = child.textAnchor;
|
anchor = child.textAnchor;
|
||||||
child = [child.subviews objectAtIndex:0];
|
child = [child.subviews firstObject];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return anchor;
|
return anchor;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)extendFontFromInheritedFont:(NSMutableDictionary *)font inheritedFont:(NSDictionary *)inheritedFont
|
|
||||||
{
|
|
||||||
NSString *fontFamily = font[@"fontFamily"];
|
|
||||||
NSNumber *fontSize = font[@"fontSize"];
|
|
||||||
NSString *fontWeight = font[@"fontWeight"];
|
|
||||||
NSString *fontStyle = font[@"fontStyle"];
|
|
||||||
|
|
||||||
BOOL fontAttributesSet = YES;
|
|
||||||
if (!fontFamily && inheritedFont[@"fontFamily"]) {
|
|
||||||
[font setObject:inheritedFont[@"fontFamily"] forKey:@"fontFamily"];
|
|
||||||
fontAttributesSet = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fontSize == nil && inheritedFont[@"fontSize"] != nil) {
|
|
||||||
[font setObject:inheritedFont[@"fontSize"] forKey:@"fontSize"];
|
|
||||||
fontAttributesSet = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fontWeight && inheritedFont[@"fontWeight"]) {
|
|
||||||
[font setObject:inheritedFont[@"fontWeight"] forKey:@"fontWeight"];
|
|
||||||
fontAttributesSet = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fontStyle && inheritedFont[@"fontStyle"]) {
|
|
||||||
[font setObject:inheritedFont[@"fontStyle"] forKey:@"fontStyle"];
|
|
||||||
fontAttributesSet = NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fontAttributesSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CTFontRef)getComputedFont
|
|
||||||
{
|
|
||||||
NSMutableDictionary *fontDict = [[NSMutableDictionary alloc] init];
|
|
||||||
[self traverseTextSuperviews:^(__kindof RNSVGText *node) {
|
|
||||||
return [self extendFontFromInheritedFont:fontDict inheritedFont:node.font];
|
|
||||||
}];
|
|
||||||
|
|
||||||
NSString *fontFamily = fontDict[@"fontFamily"];
|
|
||||||
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:fontDict[@"fontSize"]
|
|
||||||
weight:fontDict[@"fontWeight"]
|
|
||||||
style:fontDict[@"fontStyle"]
|
|
||||||
variant:nil scaleMultiplier:1.0];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (RNSVGGlyphPoint)getComputedGlyphPoint:(NSUInteger *)index glyphOffset:(CGPoint)glyphOffset
|
|
||||||
{
|
|
||||||
__block RNSVGGlyphPoint point;
|
|
||||||
point.isDeltaXSet = point.isDeltaYSet = point.isPositionXSet = point.isPositionYSet = NO;
|
|
||||||
|
|
||||||
[self traverseTextSuperviews:^(__kindof RNSVGText *node) {
|
|
||||||
if ([node class] != [RNSVGTextPath class]) {
|
|
||||||
NSUInteger index = node.lastIndex;
|
|
||||||
|
|
||||||
if (!point.isPositionXSet && node.positionX && !index) {
|
|
||||||
point.positionX = [self getWidthRelatedValue:node.positionX];
|
|
||||||
point.isPositionXSet = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!point.isDeltaXSet && node.deltaX.count > index) {
|
|
||||||
point.deltaX = [[node.deltaX objectAtIndex:index] floatValue];
|
|
||||||
point.isDeltaXSet = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!point.isPositionYSet && node.positionY && !index) {
|
|
||||||
point.positionY = [self getHeightRelatedValue:node.positionY];
|
|
||||||
point.isPositionYSet = YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!point.isDeltaYSet && node.deltaY.count > index) {
|
|
||||||
point.deltaY = [[node.deltaY objectAtIndex:index] floatValue];
|
|
||||||
point.isDeltaYSet = YES;
|
|
||||||
}
|
|
||||||
node.lastIndex++;
|
|
||||||
}
|
|
||||||
return YES;
|
|
||||||
}];
|
|
||||||
|
|
||||||
CGPoint lineOffset = [self getGlyphLineOffset];
|
|
||||||
CGFloat lastX = lineOffset.x;
|
|
||||||
CGFloat lastY = lineOffset.y;
|
|
||||||
|
|
||||||
if (point.isPositionXSet) {
|
|
||||||
lastX = point.positionX;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (point.isPositionYSet) {
|
|
||||||
lastY = point.positionY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (point.isDeltaXSet) {
|
|
||||||
lastX += point.deltaX;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (point.isDeltaYSet) {
|
|
||||||
lastY += point.deltaY;
|
|
||||||
}
|
|
||||||
|
|
||||||
[self getTextRoot].lastX = lastX;
|
|
||||||
[self getTextRoot].lastY = lastY;
|
|
||||||
|
|
||||||
point.x = lastX + glyphOffset.x;
|
|
||||||
point.y = lastY + glyphOffset.y;
|
|
||||||
|
|
||||||
return point;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
- (void)traverseTextSuperviews:(BOOL (^)(__kindof RNSVGText *node))block
|
|
||||||
{
|
|
||||||
RNSVGText *targetView = self;
|
|
||||||
block(self);
|
|
||||||
|
|
||||||
while (targetView && [targetView class] != [RNSVGText class]) {
|
|
||||||
if (![targetView isKindOfClass:[RNSVGText class]]) {
|
|
||||||
//todo: throw exception here
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
targetView = [targetView superview];
|
|
||||||
block(targetView);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (RNSVGText *)getTextRoot
|
- (RNSVGText *)getTextRoot
|
||||||
{
|
{
|
||||||
if (!_textRoot) {
|
if (!_textRoot) {
|
||||||
@@ -240,17 +119,39 @@
|
|||||||
return _textRoot;
|
return _textRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (RNSVGGlyphContext *)getGlyphContext
|
||||||
|
{
|
||||||
|
return _glyphContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)pushGlyphContext
|
||||||
|
{
|
||||||
|
[[[self getTextRoot] getGlyphContext] pushContext:self.font
|
||||||
|
deltaX:self.deltaX
|
||||||
|
deltaY:self.deltaY
|
||||||
|
positionX:self.positionX
|
||||||
|
positionY:self.positionY];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)popGlyphContext
|
||||||
|
{
|
||||||
|
[[[self getTextRoot] getGlyphContext] popContext];
|
||||||
|
}
|
||||||
|
|
||||||
- (CGPoint)getGlyphLineOffset
|
- (CGPoint)getGlyphLineOffset
|
||||||
{
|
{
|
||||||
RNSVGText *text = [self getTextRoot];
|
RNSVGText *text = [self getTextRoot];
|
||||||
return CGPointMake(text.lastX, text.lastY);
|
return CGPointMake(text.lastX, text.lastY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset Text path related attributes
|
- (CTFontRef)getFontFromContext
|
||||||
- (void)resetTextPathAttributes
|
|
||||||
{
|
{
|
||||||
self.lastIndex = 0;
|
return [[[self getTextRoot] getGlyphContext] getGlyphFont];
|
||||||
self.lastX = self.lastY = 0;
|
}
|
||||||
|
|
||||||
|
- (CGPoint)getGlyphPointFromContext:(CGPoint)offset glyphWidth:(CGFloat)glyphWidth
|
||||||
|
{
|
||||||
|
return [[[self getTextRoot] getGlyphContext] getNextGlyphPoint:(CGPoint)offset glyphWidth:glyphWidth];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -18,11 +18,6 @@
|
|||||||
[self renderGroupTo:context];
|
[self renderGroupTo:context];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGPathRef)getPath:(CGContextRef)context
|
|
||||||
{
|
|
||||||
return [self getGroupPath:context];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (RNSVGBezierTransformer *)getBezierTransformer
|
- (RNSVGBezierTransformer *)getBezierTransformer
|
||||||
{
|
{
|
||||||
RNSVGSvgView *svg = [self getSvgView];
|
RNSVGSvgView *svg = [self getSvgView];
|
||||||
|
|||||||
@@ -1,23 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
float x;
|
|
||||||
float deltaX;
|
|
||||||
BOOL isDeltaXSet;
|
|
||||||
float positionX;
|
|
||||||
BOOL isPositionXSet;
|
|
||||||
|
|
||||||
float y;
|
|
||||||
float deltaY;
|
|
||||||
BOOL isDeltaYSet;
|
|
||||||
float positionY;
|
|
||||||
BOOL isPositionYSet;
|
|
||||||
} RNSVGGlyphPoint;
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user