Prepare for new GlyphContext.

This commit is contained in:
Mikael Sand
2017-08-15 19:50:50 +03:00
parent 1c1e8a860b
commit f1657d9ddf
9 changed files with 141 additions and 40 deletions
+6
View File
@@ -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
+27
View File
@@ -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
+16
View File
@@ -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;
+63
View File
@@ -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]);
+3
View File
@@ -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;
+18
View File
@@ -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;
+8 -1
View File
@@ -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);
-6
View File
@@ -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;
-33
View File
@@ -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