mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-04 15:44:24 +00:00
Prepare for new GlyphContext.
This commit is contained in:
@@ -12,10 +12,16 @@
|
||||
#import "RNSVGCGFCRule.h"
|
||||
#import "RNSVGSvgView.h"
|
||||
#import "RNSVGPath.h"
|
||||
#import "RNSVGGlyphContext.h"
|
||||
|
||||
@interface RNSVGGroup : RNSVGPath <RNSVGContainer>
|
||||
|
||||
@property (nonatomic, strong) NSDictionary *font;
|
||||
|
||||
- (void)renderPathTo:(CGContextRef)context;
|
||||
- (void)renderGroupTo:(CGContextRef)context;
|
||||
|
||||
- (RNSVGGlyphContext *)getGlyphContext;
|
||||
- (void)pushGlyphContext;
|
||||
- (void)popGlyphContext;
|
||||
@end
|
||||
|
||||
@@ -9,15 +9,20 @@
|
||||
#import "RNSVGGroup.h"
|
||||
|
||||
@implementation RNSVGGroup
|
||||
{
|
||||
RNSVGGlyphContext *_glyphContext;
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
[self clip:context];
|
||||
[self setupGlyphContext:context];
|
||||
[self renderGroupTo:context];
|
||||
}
|
||||
|
||||
- (void)renderGroupTo:(CGContextRef)context
|
||||
{
|
||||
[self pushGlyphContext];
|
||||
RNSVGSvgView* svg = [self getSvgView];
|
||||
[self traverseSubviews:^(RNSVGNode *node) {
|
||||
if (node.responsible && !svg.responsible) {
|
||||
@@ -36,6 +41,28 @@
|
||||
|
||||
return YES;
|
||||
}];
|
||||
[self popGlyphContext];
|
||||
}
|
||||
|
||||
- (void)setupGlyphContext:(CGContextRef)context
|
||||
{
|
||||
_glyphContext = [[RNSVGGlyphContext alloc] initWithDimensions:[self getContextWidth]
|
||||
height:[self getContextHeight]];
|
||||
}
|
||||
|
||||
- (RNSVGGlyphContext *)getGlyphContext
|
||||
{
|
||||
return _glyphContext;
|
||||
}
|
||||
|
||||
- (void)pushGlyphContext
|
||||
{
|
||||
[[[self getTextRoot] getGlyphContext] pushContext:self.font];
|
||||
}
|
||||
|
||||
- (void)popGlyphContext
|
||||
{
|
||||
[[[self getTextRoot] getGlyphContext] popContext];
|
||||
}
|
||||
|
||||
- (void)renderPathTo:(CGContextRef)context
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#import <React/UIView+React.h>
|
||||
#import "RNSVGCGFCRule.h"
|
||||
#import "RNSVGSvgView.h"
|
||||
@class RNSVGGroup;
|
||||
|
||||
/**
|
||||
* RNSVG nodes are implemented as base UIViews. They should be implementation for all basic
|
||||
@@ -17,6 +18,14 @@
|
||||
|
||||
@interface RNSVGNode : UIView
|
||||
|
||||
/*
|
||||
N[1/Sqrt[2], 36]
|
||||
The inverse of the square root of 2.
|
||||
Provide enough digits for the 128-bit IEEE quad (36 significant digits).
|
||||
*/
|
||||
extern CGFloat const M_SQRT1_2l;
|
||||
extern CGFloat const DEFAULT_FONT_SIZE;
|
||||
|
||||
@property (nonatomic, strong) NSString *name;
|
||||
@property (nonatomic, assign) CGFloat opacity;
|
||||
@property (nonatomic, assign) RNSVGCGFCRule clipRule;
|
||||
@@ -27,6 +36,9 @@
|
||||
|
||||
- (void)invalidate;
|
||||
|
||||
- (RNSVGGroup *)getTextRoot;
|
||||
- (RNSVGGroup *)getParentTextRoot;
|
||||
|
||||
- (void)renderTo:(CGContextRef)context;
|
||||
|
||||
/**
|
||||
@@ -70,6 +82,10 @@
|
||||
|
||||
- (CGFloat)relativeOnHeight:(NSString *)length;
|
||||
|
||||
- (CGFloat)relativeOnOther:(NSString *)length;
|
||||
|
||||
- (CGFloat)getFontSizeFromContext;
|
||||
|
||||
- (CGFloat)getContextWidth;
|
||||
|
||||
- (CGFloat)getContextHeight;
|
||||
|
||||
@@ -9,14 +9,21 @@
|
||||
#import "RNSVGNode.h"
|
||||
#import "RNSVGContainer.h"
|
||||
#import "RNSVGClipPath.h"
|
||||
#import "RNSVGGroup.h"
|
||||
#import "RNSVGGlyphContext.h"
|
||||
|
||||
@implementation RNSVGNode
|
||||
{
|
||||
RNSVGGroup *_textRoot;
|
||||
RNSVGGlyphContext *glyphContext;
|
||||
BOOL _transparent;
|
||||
CGPathRef _cachedClipPath;
|
||||
RNSVGSvgView *_svgView;
|
||||
}
|
||||
|
||||
CGFloat const M_SQRT1_2l = 0.707106781186547524400844362104849039;
|
||||
CGFloat const DEFAULT_FONT_SIZE = 12;
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
@@ -49,6 +56,53 @@
|
||||
[container invalidate];
|
||||
}
|
||||
|
||||
- (RNSVGGroup *)getTextRoot
|
||||
{
|
||||
RNSVGNode* node = self;
|
||||
if (_textRoot == nil) {
|
||||
while (node != nil) {
|
||||
if ([node isKindOfClass:[RNSVGGroup class]] && [((RNSVGGroup*) node) getGlyphContext] != nil) {
|
||||
_textRoot = (RNSVGGroup*)node;
|
||||
break;
|
||||
}
|
||||
|
||||
UIView* parent = [node superview];
|
||||
|
||||
if (![node isKindOfClass:[RNSVGNode class]]) {
|
||||
node = nil;
|
||||
} else {
|
||||
node = (RNSVGNode*)parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _textRoot;
|
||||
}
|
||||
|
||||
- (RNSVGGroup *)getParentTextRoot
|
||||
{
|
||||
RNSVGNode* parent = (RNSVGGroup*)[self superview];
|
||||
if (![parent isKindOfClass:[RNSVGGroup class]]) {
|
||||
return nil;
|
||||
} else {
|
||||
return [parent getTextRoot];
|
||||
}
|
||||
}
|
||||
|
||||
- (CGFloat)getFontSizeFromContext
|
||||
{
|
||||
RNSVGGroup* root = [self getTextRoot];
|
||||
if (root == nil) {
|
||||
return DEFAULT_FONT_SIZE;
|
||||
}
|
||||
|
||||
if (glyphContext == nil) {
|
||||
glyphContext = [root getGlyphContext];
|
||||
}
|
||||
|
||||
return [glyphContext getFontSize];
|
||||
}
|
||||
|
||||
- (void)reactSetInheritedBackgroundColor:(UIColor *)inheritedBackgroundColor
|
||||
{
|
||||
self.backgroundColor = inheritedBackgroundColor;
|
||||
@@ -194,6 +248,15 @@
|
||||
return [RNSVGPercentageConverter stringToFloat:length relative:[self getContextHeight] offset:0];
|
||||
}
|
||||
|
||||
- (CGFloat)relativeOnOther:(NSString *)length
|
||||
{
|
||||
CGFloat width = [self getContextWidth];
|
||||
CGFloat height = [self getContextHeight];
|
||||
CGFloat powX = width * width;
|
||||
CGFloat powY = height * height;
|
||||
CGFloat r = sqrt(powX + powY) * M_SQRT1_2l;
|
||||
return [RNSVGPercentageConverter stringToFloat:length relative:r offset:0];}
|
||||
|
||||
- (CGFloat)getContextWidth
|
||||
{
|
||||
return CGRectGetWidth([[self getSvgView] getContextBounds]);
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
@interface RNSVGGlyphContext : NSObject
|
||||
|
||||
- (instancetype)initWithDimensions:(CGFloat)width height:(CGFloat)height;
|
||||
|
||||
- (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;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#import "RNSVGGlyphContext.h"
|
||||
#import "RNSVGPercentageConverter.h"
|
||||
#import <React/RCTFont.h>
|
||||
#import "RNSVGNode.h"
|
||||
|
||||
@implementation RNSVGGlyphContext
|
||||
{
|
||||
@@ -21,6 +22,7 @@
|
||||
CGPoint _currentLocation;
|
||||
CGFloat _width;
|
||||
CGFloat _height;
|
||||
CGFloat _fontSize;
|
||||
}
|
||||
|
||||
- (instancetype)initWithDimensions:(CGFloat)width height:(CGFloat)height
|
||||
@@ -34,10 +36,26 @@
|
||||
_deltaYContext = [[NSMutableArray alloc] init];
|
||||
_xContext = [[NSMutableArray alloc] init];
|
||||
_currentLocation = CGPointZero;
|
||||
_fontSize = DEFAULT_FONT_SIZE;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (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;
|
||||
|
||||
@@ -70,10 +70,17 @@
|
||||
CTFontRef font = [self getFontFromContext];
|
||||
|
||||
// Create a dictionary for this font
|
||||
CFDictionaryRef attributes = (__bridge CFDictionaryRef)@{
|
||||
CFDictionaryRef attributes;
|
||||
if (font != nil) {
|
||||
attributes = (__bridge CFDictionaryRef)@{
|
||||
(NSString *)kCTFontAttributeName: (__bridge id)font,
|
||||
(NSString *)kCTForegroundColorFromContextAttributeName: @YES
|
||||
};
|
||||
} else {
|
||||
attributes = (__bridge CFDictionaryRef)@{
|
||||
(NSString *)kCTForegroundColorFromContextAttributeName: @YES
|
||||
};
|
||||
}
|
||||
|
||||
CFStringRef string = (__bridge CFStringRef)text;
|
||||
CFAttributedStringRef attrString = CFAttributedStringCreate(kCFAllocatorDefault, string, attributes);
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "RNSVGGroup.h"
|
||||
#import "RNSVGTextAnchor.h"
|
||||
#import "RNSVGGlyphContext.h"
|
||||
|
||||
@interface RNSVGText : RNSVGGroup
|
||||
|
||||
@@ -18,15 +17,10 @@
|
||||
@property (nonatomic, strong) NSArray<NSString *> *deltaY;
|
||||
@property (nonatomic, strong) NSArray<NSString *> *positionX;
|
||||
@property (nonatomic, strong) NSArray<NSString *> *positionY;
|
||||
@property (nonatomic, strong) NSDictionary *font;
|
||||
|
||||
- (RNSVGText *)getTextRoot;
|
||||
- (void)releaseCachedPath;
|
||||
- (CGPathRef)getGroupPath:(CGContextRef)context;
|
||||
|
||||
- (RNSVGGlyphContext *)getGlyphContext;
|
||||
- (void)pushGlyphContext;
|
||||
- (void)popGlyphContext;
|
||||
- (CTFontRef)getFontFromContext;
|
||||
- (CGPoint)getGlyphPointFromContext:(CGPoint)offset glyphWidth:(CGFloat)glyphWidth;
|
||||
|
||||
|
||||
@@ -13,10 +13,6 @@
|
||||
#import "RNSVGGlyphContext.h"
|
||||
|
||||
@implementation RNSVGText
|
||||
{
|
||||
RNSVGText *_textRoot;
|
||||
RNSVGGlyphContext *_glyphContext;
|
||||
}
|
||||
|
||||
- (void)setTextAnchor:(RNSVGTextAnchor)textAnchor
|
||||
{
|
||||
@@ -28,7 +24,6 @@
|
||||
{
|
||||
[self clip:context];
|
||||
CGContextSaveGState(context);
|
||||
[self setupGlyphContext:context];
|
||||
|
||||
CGPathRef path = [self getGroupPath:context];
|
||||
CGAffineTransform transform = [self getAlignTransform:path];
|
||||
@@ -43,12 +38,6 @@
|
||||
CGPathRelease(transformedPath);
|
||||
}
|
||||
|
||||
- (void)setupGlyphContext:(CGContextRef)context
|
||||
{
|
||||
_glyphContext = [[RNSVGGlyphContext alloc] initWithDimensions:[self getContextWidth]
|
||||
height:[self getContextHeight]];
|
||||
}
|
||||
|
||||
// release the cached CGPathRef for RNSVGTSpan
|
||||
- (void)releaseCachedPath
|
||||
{
|
||||
@@ -70,7 +59,6 @@
|
||||
|
||||
- (CGPathRef)getPath:(CGContextRef)context
|
||||
{
|
||||
[self setupGlyphContext:context];
|
||||
CGPathRef groupPath = [self getGroupPath:context];
|
||||
CGAffineTransform transform = [self getAlignTransform:groupPath];
|
||||
[self releaseCachedPath];
|
||||
@@ -117,27 +105,6 @@
|
||||
return anchor;
|
||||
}
|
||||
|
||||
- (RNSVGText *)getTextRoot
|
||||
{
|
||||
if (!_textRoot) {
|
||||
_textRoot = self;
|
||||
while (_textRoot && [_textRoot class] != [RNSVGText class]) {
|
||||
if (![_textRoot isKindOfClass:[RNSVGText class]]) {
|
||||
//todo: throw exception here
|
||||
break;
|
||||
}
|
||||
_textRoot = (RNSVGText*)[_textRoot superview];
|
||||
}
|
||||
}
|
||||
|
||||
return _textRoot;
|
||||
}
|
||||
|
||||
- (RNSVGGlyphContext *)getGlyphContext
|
||||
{
|
||||
return _glyphContext;
|
||||
}
|
||||
|
||||
- (void)pushGlyphContext
|
||||
{
|
||||
[[[self getTextRoot] getGlyphContext] pushContext:self.font
|
||||
|
||||
Reference in New Issue
Block a user