mirror of
https://github.com/zoriya/react-native-svg.git
synced 2025-12-19 21:45:10 +00:00
flattern text into several spans
flattern text into several spans (step 1, not finish yet)
This commit is contained in:
47
elements/Span.js
Normal file
47
elements/Span.js
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import createReactNativeComponentClass from 'react/lib/createReactNativeComponentClass';
|
||||||
|
import {SpanAttributes} from '../lib/attributes';
|
||||||
|
import Shape from './Shape';
|
||||||
|
import {pathProps, numberProp} from '../lib/props';
|
||||||
|
|
||||||
|
class Span extends Shape {
|
||||||
|
static displayName = 'Span';
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
...pathProps,
|
||||||
|
x1: numberProp.isRequired,
|
||||||
|
x2: numberProp.isRequired,
|
||||||
|
y1: numberProp.isRequired,
|
||||||
|
y2: numberProp.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
x1: 0,
|
||||||
|
y1: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
setNativeProps = (...args) => {
|
||||||
|
this.root.setNativeProps(...args);
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let props = this.props;
|
||||||
|
return <RNSVGLine
|
||||||
|
ref={ele => {this.root = ele;}}
|
||||||
|
{...this.extractProps(props)}
|
||||||
|
x1={props.x1.toString()}
|
||||||
|
y1={props.y1.toString()}
|
||||||
|
x2={props.x2.toString()}
|
||||||
|
y2={props.y2.toString()}
|
||||||
|
/>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const RNSVGSpan = createReactNativeComponentClass({
|
||||||
|
validAttributes: SpanAttributes,
|
||||||
|
uiViewClassName: 'RNSVGSpan'
|
||||||
|
});
|
||||||
|
|
||||||
|
export default Span;
|
||||||
@@ -28,7 +28,11 @@ class Text extends Shape {
|
|||||||
let props = this.props;
|
let props = this.props;
|
||||||
return <RNSVGText
|
return <RNSVGText
|
||||||
ref={ele => {this.root = ele;}}
|
ref={ele => {this.root = ele;}}
|
||||||
{...this.extractProps({...props})}
|
{...this.extractProps({
|
||||||
|
...props,
|
||||||
|
x: null,
|
||||||
|
y: null
|
||||||
|
})}
|
||||||
{...extractText(props)}
|
{...extractText(props)}
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
1039D2951CE71EC2001E90A8 /* RNSVGText.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2901CE71EC2001E90A8 /* RNSVGText.m */; };
|
1039D2951CE71EC2001E90A8 /* RNSVGText.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2901CE71EC2001E90A8 /* RNSVGText.m */; };
|
||||||
1039D2A01CE72177001E90A8 /* RCTConvert+RNSVG.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D29C1CE72177001E90A8 /* RCTConvert+RNSVG.m */; };
|
1039D2A01CE72177001E90A8 /* RCTConvert+RNSVG.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D29C1CE72177001E90A8 /* RCTConvert+RNSVG.m */; };
|
||||||
1039D2B01CE72F27001E90A8 /* RNSVGPercentageConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2AF1CE72F27001E90A8 /* RNSVGPercentageConverter.m */; };
|
1039D2B01CE72F27001E90A8 /* RNSVGPercentageConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1039D2AF1CE72F27001E90A8 /* RNSVGPercentageConverter.m */; };
|
||||||
|
107CD53E1D7166B700F0A7AC /* RNSVGTSpanManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 107CD53D1D7166B700F0A7AC /* RNSVGTSpanManager.m */; };
|
||||||
|
107CD5401D71672E00F0A7AC /* RNSVGTSpan.m in Sources */ = {isa = PBXBuildFile; fileRef = 107CD53F1D71672E00F0A7AC /* RNSVGTSpan.m */; };
|
||||||
10ABC7331D435915006CCF6E /* RNSVGViewBoxManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10ABC7321D435915006CCF6E /* RNSVGViewBoxManager.m */; };
|
10ABC7331D435915006CCF6E /* RNSVGViewBoxManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10ABC7321D435915006CCF6E /* RNSVGViewBoxManager.m */; };
|
||||||
10ABC7361D43595E006CCF6E /* RNSVGViewBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 10ABC7351D43595E006CCF6E /* RNSVGViewBox.m */; };
|
10ABC7361D43595E006CCF6E /* RNSVGViewBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 10ABC7351D43595E006CCF6E /* RNSVGViewBox.m */; };
|
||||||
10BA0D341CE74E3100887C2B /* RNSVGCircleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D1D1CE74E3100887C2B /* RNSVGCircleManager.m */; };
|
10BA0D341CE74E3100887C2B /* RNSVGCircleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 10BA0D1D1CE74E3100887C2B /* RNSVGCircleManager.m */; };
|
||||||
@@ -100,6 +102,10 @@
|
|||||||
1039D2A11CE721A7001E90A8 /* RNSVGContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGContainer.h; sourceTree = "<group>"; };
|
1039D2A11CE721A7001E90A8 /* RNSVGContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGContainer.h; sourceTree = "<group>"; };
|
||||||
1039D2AE1CE72F27001E90A8 /* RNSVGPercentageConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGPercentageConverter.h; path = Utils/RNSVGPercentageConverter.h; sourceTree = "<group>"; };
|
1039D2AE1CE72F27001E90A8 /* RNSVGPercentageConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGPercentageConverter.h; path = Utils/RNSVGPercentageConverter.h; sourceTree = "<group>"; };
|
||||||
1039D2AF1CE72F27001E90A8 /* RNSVGPercentageConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGPercentageConverter.m; path = Utils/RNSVGPercentageConverter.m; sourceTree = "<group>"; };
|
1039D2AF1CE72F27001E90A8 /* RNSVGPercentageConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGPercentageConverter.m; path = Utils/RNSVGPercentageConverter.m; sourceTree = "<group>"; };
|
||||||
|
107CD53B1D7166A000F0A7AC /* RNSVGTSpan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RNSVGTSpan.h; path = Text/RNSVGTSpan.h; sourceTree = "<group>"; };
|
||||||
|
107CD53C1D7166B700F0A7AC /* RNSVGTSpanManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGTSpanManager.h; sourceTree = "<group>"; };
|
||||||
|
107CD53D1D7166B700F0A7AC /* RNSVGTSpanManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGTSpanManager.m; sourceTree = "<group>"; };
|
||||||
|
107CD53F1D71672E00F0A7AC /* RNSVGTSpan.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RNSVGTSpan.m; path = Text/RNSVGTSpan.m; sourceTree = "<group>"; };
|
||||||
10ABC7311D435915006CCF6E /* RNSVGViewBoxManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGViewBoxManager.h; sourceTree = "<group>"; };
|
10ABC7311D435915006CCF6E /* RNSVGViewBoxManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGViewBoxManager.h; sourceTree = "<group>"; };
|
||||||
10ABC7321D435915006CCF6E /* RNSVGViewBoxManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGViewBoxManager.m; sourceTree = "<group>"; };
|
10ABC7321D435915006CCF6E /* RNSVGViewBoxManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNSVGViewBoxManager.m; sourceTree = "<group>"; };
|
||||||
10ABC7341D43595E006CCF6E /* RNSVGViewBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGViewBox.h; sourceTree = "<group>"; };
|
10ABC7341D43595E006CCF6E /* RNSVGViewBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNSVGViewBox.h; sourceTree = "<group>"; };
|
||||||
@@ -217,6 +223,8 @@
|
|||||||
0CF68AF81AF0549300FF9E5C /* ViewManagers */ = {
|
0CF68AF81AF0549300FF9E5C /* ViewManagers */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
107CD53C1D7166B700F0A7AC /* RNSVGTSpanManager.h */,
|
||||||
|
107CD53D1D7166B700F0A7AC /* RNSVGTSpanManager.m */,
|
||||||
10ABC7311D435915006CCF6E /* RNSVGViewBoxManager.h */,
|
10ABC7311D435915006CCF6E /* RNSVGViewBoxManager.h */,
|
||||||
10ABC7321D435915006CCF6E /* RNSVGViewBoxManager.m */,
|
10ABC7321D435915006CCF6E /* RNSVGViewBoxManager.m */,
|
||||||
10BEC1BE1D3F680F00FDCB19 /* RNSVGLinearGradientManager.h */,
|
10BEC1BE1D3F680F00FDCB19 /* RNSVGLinearGradientManager.h */,
|
||||||
@@ -275,6 +283,8 @@
|
|||||||
children = (
|
children = (
|
||||||
103371331D41D3400028AF13 /* RNSVGBezierPath.h */,
|
103371331D41D3400028AF13 /* RNSVGBezierPath.h */,
|
||||||
103371311D41C5C90028AF13 /* RNSVGBezierPath.m */,
|
103371311D41C5C90028AF13 /* RNSVGBezierPath.m */,
|
||||||
|
107CD53B1D7166A000F0A7AC /* RNSVGTSpan.h */,
|
||||||
|
107CD53F1D71672E00F0A7AC /* RNSVGTSpan.m */,
|
||||||
1039D28F1CE71EC2001E90A8 /* RNSVGText.h */,
|
1039D28F1CE71EC2001E90A8 /* RNSVGText.h */,
|
||||||
1039D2901CE71EC2001E90A8 /* RNSVGText.m */,
|
1039D2901CE71EC2001E90A8 /* RNSVGText.m */,
|
||||||
1039D2911CE71EC2001E90A8 /* RNSVGTextFrame.h */,
|
1039D2911CE71EC2001E90A8 /* RNSVGTextFrame.h */,
|
||||||
@@ -392,6 +402,7 @@
|
|||||||
1039D2951CE71EC2001E90A8 /* RNSVGText.m in Sources */,
|
1039D2951CE71EC2001E90A8 /* RNSVGText.m in Sources */,
|
||||||
10BA0D3B1CE74E3100887C2B /* RNSVGRectManager.m in Sources */,
|
10BA0D3B1CE74E3100887C2B /* RNSVGRectManager.m in Sources */,
|
||||||
0CF68B071AF0549300FF9E5C /* RNSVGRenderable.m in Sources */,
|
0CF68B071AF0549300FF9E5C /* RNSVGRenderable.m in Sources */,
|
||||||
|
107CD53E1D7166B700F0A7AC /* RNSVGTSpanManager.m in Sources */,
|
||||||
1039D2891CE71EB7001E90A8 /* RNSVGGroup.m in Sources */,
|
1039D2891CE71EB7001E90A8 /* RNSVGGroup.m in Sources */,
|
||||||
10ED4A9E1CF0656A0078BC02 /* RNSVGClipPathManager.m in Sources */,
|
10ED4A9E1CF0656A0078BC02 /* RNSVGClipPathManager.m in Sources */,
|
||||||
10BEC1C61D3F7BD300FDCB19 /* RNSVGBrushConverter.m in Sources */,
|
10BEC1C61D3F7BD300FDCB19 /* RNSVGBrushConverter.m in Sources */,
|
||||||
@@ -400,6 +411,7 @@
|
|||||||
10BA0D3E1CE74E3100887C2B /* RNSVGSvgViewManager.m in Sources */,
|
10BA0D3E1CE74E3100887C2B /* RNSVGSvgViewManager.m in Sources */,
|
||||||
0CF68B0F1AF0549300FF9E5C /* RNSVGSolidColorBrush.m in Sources */,
|
0CF68B0F1AF0549300FF9E5C /* RNSVGSolidColorBrush.m in Sources */,
|
||||||
10BA0D3A1CE74E3100887C2B /* RNSVGPathManager.m in Sources */,
|
10BA0D3A1CE74E3100887C2B /* RNSVGPathManager.m in Sources */,
|
||||||
|
107CD5401D71672E00F0A7AC /* RNSVGTSpan.m in Sources */,
|
||||||
103371321D41C5C90028AF13 /* RNSVGBezierPath.m in Sources */,
|
103371321D41C5C90028AF13 /* RNSVGBezierPath.m in Sources */,
|
||||||
10BA0D3C1CE74E3100887C2B /* RNSVGRenderableManager.m in Sources */,
|
10BA0D3C1CE74E3100887C2B /* RNSVGRenderableManager.m in Sources */,
|
||||||
10BEC1BD1D3F66F500FDCB19 /* RNSVGRadialGradient.m in Sources */,
|
10BEC1BD1D3F66F500FDCB19 /* RNSVGRadialGradient.m in Sources */,
|
||||||
|
|||||||
@@ -10,10 +10,10 @@
|
|||||||
#import "RNSVGPath.h"
|
#import "RNSVGPath.h"
|
||||||
#import "RNSVGTextFrame.h"
|
#import "RNSVGTextFrame.h"
|
||||||
|
|
||||||
@interface RNSVGText : RNSVGPath
|
@interface RNSVGTSpan : RNSVGPath
|
||||||
|
|
||||||
@property (nonatomic, assign) CTTextAlignment alignment;
|
@property (nonatomic, assign) NSString *line;
|
||||||
@property (nonatomic, assign) RNSVGTextFrame textFrame;
|
@property (nonatomic, assign) NSString *dx;
|
||||||
@property (nonatomic, assign) NSString
|
@property (nonatomic, assign) NSString *dy;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -6,131 +6,17 @@
|
|||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "RNSVGText.h"
|
#import "RNSVGTSpan.h"
|
||||||
#import "RNSVGBezierPath.h"
|
#import "RNSVGBezierPath.h"
|
||||||
#import <CoreText/CoreText.h>
|
#import <CoreText/CoreText.h>
|
||||||
|
|
||||||
@implementation RNSVGText
|
@implementation RNSVGTSpan
|
||||||
|
|
||||||
static void RNSVGFreeTextFrame(RNSVGTextFrame frame)
|
|
||||||
{
|
|
||||||
if (frame.count) {
|
|
||||||
// We must release each line before freeing up this struct
|
|
||||||
for (int i = 0; i < frame.count; i++) {
|
|
||||||
CFRelease(frame.lines[i]);
|
|
||||||
}
|
|
||||||
free(frame.lines);
|
|
||||||
free(frame.widths);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setAlignment:(CTTextAlignment)alignment
|
|
||||||
{
|
|
||||||
[self invalidate];
|
|
||||||
_alignment = alignment;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setTextFrame:(RNSVGTextFrame)textFrame
|
|
||||||
{
|
|
||||||
RNSVGFreeTextFrame(_textFrame);
|
|
||||||
[self invalidate];
|
|
||||||
_textFrame = textFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)setPath:(NSArray *)path
|
|
||||||
{
|
|
||||||
if (path == _path) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
[self invalidate];
|
|
||||||
_path = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)dealloc
|
|
||||||
{
|
|
||||||
RNSVGFreeTextFrame(_textFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CGPathRef)getPath:(CGContextRef)context
|
- (CGPathRef)getPath:(CGContextRef)context
|
||||||
{
|
{
|
||||||
CGMutablePathRef path = CGPathCreateMutable();
|
CGMutablePathRef path = CGPathCreateMutable();
|
||||||
RNSVGTextFrame frame = self.textFrame;
|
|
||||||
for (int i = 0; i < frame.count; i++) {
|
|
||||||
CGFloat shift;
|
|
||||||
CGFloat width = frame.widths[i];
|
|
||||||
switch (self.alignment) {
|
|
||||||
case kCTTextAlignmentRight:
|
|
||||||
shift = width;
|
|
||||||
break;
|
|
||||||
case kCTTextAlignmentCenter:
|
|
||||||
shift = width / 2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
shift = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// We should consider snapping this shift to device pixels to improve rendering quality
|
|
||||||
// when a line has subpixel width.
|
|
||||||
CGAffineTransform offset = CGAffineTransformMakeTranslation(-shift, frame.baseLine + frame.lineHeight * i + (self.path ? -frame.lineHeight : 0));
|
|
||||||
|
|
||||||
CGMutablePathRef line = [self setLinePath:frame.lines[i]];
|
|
||||||
CGPathAddPath(path, &offset, line);
|
|
||||||
CGPathRelease(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (CGPathRef)CFAutorelease(path);
|
return (CGPathRef)CFAutorelease(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (CGMutablePathRef)setLinePath:(CTLineRef)line
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
RNSVGBezierPath *bezierPath = [[RNSVGBezierPath alloc] initWithBezierCurves:self.path];
|
|
||||||
|
|
||||||
for(CFIndex i = 0; i < runGlyphCount; ++i) {
|
|
||||||
CGPathRef letter = CTFontCreatePathForGlyph(runFont, glyphs[i], nil);
|
|
||||||
CGPoint point = positions[i];
|
|
||||||
|
|
||||||
if (letter) {
|
|
||||||
CGAffineTransform transform;
|
|
||||||
|
|
||||||
// draw glyphs along path
|
|
||||||
if (self.path) {
|
|
||||||
transform = [bezierPath transformAtDistance:point.x];
|
|
||||||
|
|
||||||
// break loop if line reaches the end of the Path.
|
|
||||||
if (!transform.a || !transform.d) {
|
|
||||||
CGPathRelease(letter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
transform = CGAffineTransformScale(transform, 1.0, -1.0);
|
|
||||||
} else {
|
|
||||||
transform = CGAffineTransformTranslate(upsideDown, point.x, point.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CGPathAddPath(path, &transform, letter);
|
|
||||||
}
|
|
||||||
|
|
||||||
CGPathRelease(letter);
|
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -10,10 +10,9 @@
|
|||||||
#import "RNSVGPath.h"
|
#import "RNSVGPath.h"
|
||||||
#import "RNSVGTextFrame.h"
|
#import "RNSVGTextFrame.h"
|
||||||
|
|
||||||
@interface RNSVGText : RNSVGPath
|
@interface RNSVGText : RNSVGRenderable
|
||||||
|
|
||||||
@property (nonatomic, assign) CTTextAlignment alignment;
|
@property (nonatomic, assign) CTTextAlignment alignment;
|
||||||
@property (nonatomic, assign) RNSVGTextFrame textFrame;
|
|
||||||
@property (nonatomic, copy) NSArray<NSArray *> *path;
|
@property (nonatomic, copy) NSArray<NSArray *> *path;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -12,30 +12,30 @@
|
|||||||
|
|
||||||
@implementation RNSVGText
|
@implementation RNSVGText
|
||||||
|
|
||||||
static void RNSVGFreeTextFrame(RNSVGTextFrame frame)
|
//static void RNSVGFreeTextFrame(RNSVGTextFrame frame)
|
||||||
{
|
//{
|
||||||
if (frame.count) {
|
// if (frame.count) {
|
||||||
// We must release each line before freeing up this struct
|
// // We must release each line before freeing up this struct
|
||||||
for (int i = 0; i < frame.count; i++) {
|
// for (int i = 0; i < frame.count; i++) {
|
||||||
CFRelease(frame.lines[i]);
|
// CFRelease(frame.lines[i]);
|
||||||
}
|
// }
|
||||||
free(frame.lines);
|
// free(frame.lines);
|
||||||
free(frame.widths);
|
// free(frame.widths);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
- (void)setAlignment:(CTTextAlignment)alignment
|
- (void)setAlignment:(CTTextAlignment)alignment
|
||||||
{
|
{
|
||||||
[self invalidate];
|
[self invalidate];
|
||||||
_alignment = alignment;
|
_alignment = alignment;
|
||||||
}
|
}
|
||||||
|
//
|
||||||
- (void)setTextFrame:(RNSVGTextFrame)textFrame
|
//- (void)setTextFrame:(RNSVGTextFrame)textFrame
|
||||||
{
|
//{
|
||||||
RNSVGFreeTextFrame(_textFrame);
|
// RNSVGFreeTextFrame(_textFrame);
|
||||||
[self invalidate];
|
// [self invalidate];
|
||||||
_textFrame = textFrame;
|
// _textFrame = textFrame;
|
||||||
}
|
//}
|
||||||
|
|
||||||
- (void)setPath:(NSArray *)path
|
- (void)setPath:(NSArray *)path
|
||||||
{
|
{
|
||||||
@@ -46,37 +46,37 @@ static void RNSVGFreeTextFrame(RNSVGTextFrame frame)
|
|||||||
_path = path;
|
_path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc
|
//- (void)dealloc
|
||||||
{
|
//{
|
||||||
RNSVGFreeTextFrame(_textFrame);
|
// RNSVGFreeTextFrame(_textFrame);
|
||||||
}
|
//}
|
||||||
|
|
||||||
- (CGPathRef)getPath:(CGContextRef)context
|
- (CGPathRef)getPath:(CGContextRef)context
|
||||||
{
|
{
|
||||||
CGMutablePathRef path = CGPathCreateMutable();
|
CGMutablePathRef path = CGPathCreateMutable();
|
||||||
RNSVGTextFrame frame = self.textFrame;
|
// RNSVGTextFrame frame = self.textFrame;
|
||||||
for (int i = 0; i < frame.count; i++) {
|
// for (int i = 0; i < frame.count; i++) {
|
||||||
CGFloat shift;
|
// CGFloat shift;
|
||||||
CGFloat width = frame.widths[i];
|
// CGFloat width = frame.widths[i];
|
||||||
switch (self.alignment) {
|
// switch (self.alignment) {
|
||||||
case kCTTextAlignmentRight:
|
// case kCTTextAlignmentRight:
|
||||||
shift = width;
|
// shift = width;
|
||||||
break;
|
// break;
|
||||||
case kCTTextAlignmentCenter:
|
// case kCTTextAlignmentCenter:
|
||||||
shift = width / 2;
|
// shift = width / 2;
|
||||||
break;
|
// break;
|
||||||
default:
|
// default:
|
||||||
shift = 0;
|
// shift = 0;
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
// We should consider snapping this shift to device pixels to improve rendering quality
|
// // We should consider snapping this shift to device pixels to improve rendering quality
|
||||||
// when a line has subpixel width.
|
// // when a line has subpixel width.
|
||||||
CGAffineTransform offset = CGAffineTransformMakeTranslation(-shift, frame.baseLine + frame.lineHeight * i + (self.path ? -frame.lineHeight : 0));
|
// CGAffineTransform offset = CGAffineTransformMakeTranslation(-shift, frame.baseLine + frame.lineHeight * i + (self.path ? -frame.lineHeight : 0));
|
||||||
|
//
|
||||||
CGMutablePathRef line = [self setLinePath:frame.lines[i]];
|
// CGMutablePathRef line = [self setLinePath:frame.lines[i]];
|
||||||
CGPathAddPath(path, &offset, line);
|
// CGPathAddPath(path, &offset, line);
|
||||||
CGPathRelease(line);
|
// CGPathRelease(line);
|
||||||
}
|
// }
|
||||||
|
|
||||||
return (CGPathRef)CFAutorelease(path);
|
return (CGPathRef)CFAutorelease(path);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ RCT_EXPORT_MODULE()
|
|||||||
return [RNSVGTSpan new];
|
return [RNSVGTSpan new];
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_EXPORT_VIEW_PROPERTY(alignment, CTTextAlignment)
|
RCT_EXPORT_VIEW_PROPERTY(line, NSString)
|
||||||
RCT_REMAP_VIEW_PROPERTY(frame, textFrame, RNSVGTextFrame)
|
|
||||||
RCT_EXPORT_VIEW_PROPERTY(dx, NSString)
|
RCT_EXPORT_VIEW_PROPERTY(dx, NSString)
|
||||||
RCT_EXPORT_VIEW_PROPERTY(dy, NSString)
|
RCT_EXPORT_VIEW_PROPERTY(dy, NSString)
|
||||||
|
|
||||||
|
|||||||
@@ -80,21 +80,18 @@ const PathAttributes = merge({
|
|||||||
}
|
}
|
||||||
}, RenderableAttributes);
|
}, RenderableAttributes);
|
||||||
|
|
||||||
const FontAttributes = merge({
|
const SpanAttributes = merge({
|
||||||
fontFamily: true,
|
fontFamily: true,
|
||||||
fontSize: true,
|
fontSize: true,
|
||||||
fontWeight: true,
|
fontWeight: true,
|
||||||
fontStyle: true
|
fontStyle: true,
|
||||||
}, RenderableAttributes);
|
|
||||||
|
|
||||||
const TSpanAttributes = merge({
|
|
||||||
line: true
|
line: true
|
||||||
}, FontAttributes);
|
}, RenderableAttributes);
|
||||||
|
|
||||||
|
|
||||||
const TextAttributes = merge({
|
const TextAttributes = merge({
|
||||||
alignment: true
|
alignment: true
|
||||||
}, FontAttributes);
|
}, RenderableAttributes);
|
||||||
|
|
||||||
const ClipPathAttributes = {
|
const ClipPathAttributes = {
|
||||||
name: true
|
name: true
|
||||||
@@ -166,7 +163,7 @@ const RectAttributes = merge({
|
|||||||
export {
|
export {
|
||||||
PathAttributes,
|
PathAttributes,
|
||||||
TextAttributes,
|
TextAttributes,
|
||||||
TSpanAttributes,
|
SpanAttributes,
|
||||||
GroupAttributes,
|
GroupAttributes,
|
||||||
ClipPathAttributes,
|
ClipPathAttributes,
|
||||||
CircleAttributes,
|
CircleAttributes,
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
import React, {
|
|
||||||
Children
|
|
||||||
} from 'react';
|
|
||||||
|
|
||||||
import TSpan from '../../elements/TSpan';
|
|
||||||
import extractTextContent from './extractTextContent';
|
import extractTextContent from './extractTextContent';
|
||||||
import SerializablePath from '../SerializablePath';
|
import SerializablePath from '../SerializablePath';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import extractTextContent from './extractTextContent';
|
import SerializablePath from '../SerializablePath';
|
||||||
import extractSpan from './extractSpan';
|
import _ from 'lodash';
|
||||||
|
const fontRegExp = /^\s*((?:(?:normal|bold|italic)\s+)*)(?:(\d+(?:\.\d+)?)[ptexm%]*(?:\s*\/.*?)?\s+)?\s*"?([^"]*)/i;
|
||||||
|
const fontFamilyPrefix = /^[\s"']*/;
|
||||||
|
const fontFamilySuffix = /[\s"']*$/;
|
||||||
|
const spaceReg = /\s+/;
|
||||||
|
const commaReg = /,/;
|
||||||
|
|
||||||
const anchors = {
|
const anchors = {
|
||||||
end: 1,
|
end: 1,
|
||||||
@@ -7,37 +12,98 @@ const anchors = {
|
|||||||
start: 0
|
start: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let cachedFontObjectsFromString = {};
|
||||||
|
|
||||||
|
function extractSingleFontFamily(fontFamilyString) {
|
||||||
|
// SVG on the web allows for multiple font-families to be specified.
|
||||||
|
// For compatibility, we extract the first font-family, hoping
|
||||||
|
// we'll get a match.
|
||||||
|
return fontFamilyString ? fontFamilyString.split(commaReg)[0]
|
||||||
|
.replace(fontFamilyPrefix, '')
|
||||||
|
.replace(fontFamilySuffix, '') : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseFontString(font) {
|
||||||
|
if (cachedFontObjectsFromString.hasOwnProperty(font)) {
|
||||||
|
return cachedFontObjectsFromString[font];
|
||||||
|
}
|
||||||
|
let match = fontRegExp.exec(font);
|
||||||
|
if (!match) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let fontFamily = extractSingleFontFamily(match[3]);
|
||||||
|
let fontSize = +match[2] || 12;
|
||||||
|
let isBold = /bold/.exec(match[1]);
|
||||||
|
let isItalic = /italic/.exec(match[1]);
|
||||||
|
cachedFontObjectsFromString[font] = {
|
||||||
|
fontFamily: fontFamily,
|
||||||
|
fontSize: fontSize,
|
||||||
|
fontWeight: isBold ? 'bold' : 'normal',
|
||||||
|
fontStyle: isItalic ? 'italic' : 'normal'
|
||||||
|
};
|
||||||
|
return cachedFontObjectsFromString[font];
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractFont(props) {
|
||||||
|
let font = props.font;
|
||||||
|
let fontSize = +props.fontSize;
|
||||||
|
|
||||||
|
let ownedFont = {
|
||||||
|
fontFamily: extractSingleFontFamily(props.fontFamily),
|
||||||
|
fontSize: isNaN(fontSize) ? null : fontSize,
|
||||||
|
fontWeight: props.fontWeight,
|
||||||
|
fontStyle: props.fontStyle
|
||||||
|
};
|
||||||
|
|
||||||
|
if (typeof props.font === 'string') {
|
||||||
|
font = parseFontString(props.font);
|
||||||
|
}
|
||||||
|
ownedFont = _.pickBy(ownedFont, prop => !_.isNil(prop));
|
||||||
|
|
||||||
|
return _.defaults(ownedFont, font);
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseText(props, inheritedProps) {
|
||||||
|
let {
|
||||||
|
children,
|
||||||
|
dx = '',
|
||||||
|
dy = ''
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
if (typeof children === 'string') {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(dx, dy, children);
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseDelta(delta) {
|
||||||
|
return delta.toString().trim().split(spaceReg);
|
||||||
|
}
|
||||||
|
|
||||||
export default function(props) {
|
export default function(props) {
|
||||||
let children = extractTextContent(props.children);
|
parseText(props, null);
|
||||||
let extractedProps = extractSpan(props);
|
|
||||||
let firstSpan = children[0];
|
|
||||||
let alignment;
|
let alignment;
|
||||||
let {dx, dy} = extractedProps;
|
//if (firstSpan && firstSpan.props.hasOwnProperty('textAnchor')) {
|
||||||
let maxDeltaLength = Math.max(dx.length, dy.length);
|
// alignment = anchors[firstSpan.props.textAnchor];
|
||||||
|
//} else if (anchors[props.textAnchor]) {
|
||||||
if (firstSpan && firstSpan.props.hasOwnProperty('textAnchor')) {
|
// alignment = anchors[props.textAnchor];
|
||||||
alignment = anchors[firstSpan.props.textAnchor];
|
//}
|
||||||
} else if (anchors[props.textAnchor]) {
|
//
|
||||||
alignment = anchors[props.textAnchor];
|
//if (!alignment) {
|
||||||
}
|
// alignment = 0;
|
||||||
|
//}
|
||||||
if (!alignment) {
|
|
||||||
alignment = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < maxDeltaLength; i++) {
|
|
||||||
console.log(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(extractedProps);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
alignment,
|
//alignment,
|
||||||
children,
|
//children,
|
||||||
fontFamily: 'Helvetica Neue',
|
fontFamily: 'Helvetica Neue',
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontStyle: 'normal',
|
fontStyle: 'normal',
|
||||||
fontWeight: 'normal',
|
fontWeight: 'normal',
|
||||||
...extractedProps
|
...extractFont(props)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user