mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-09 01:25:01 +00:00
first step of TSpan
This commit is contained in:
+15
-32
@@ -17,30 +17,6 @@ function arrayDiffer(a, b) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function fontAndLinesDiffer(a, b) {
|
||||
if (a === b) {
|
||||
return false;
|
||||
}
|
||||
if (a.font !== b.font) {
|
||||
if (a.font === null) {
|
||||
return true;
|
||||
}
|
||||
if (b.font === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
a.font.fontFamily !== b.font.fontFamily ||
|
||||
a.font.fontSize !== b.font.fontSize ||
|
||||
a.font.fontWeight !== b.font.fontWeight ||
|
||||
a.font.fontStyle !== b.font.fontStyle
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return arrayDiffer(a.lines, b.lines);
|
||||
}
|
||||
|
||||
const ViewBoxAttributes = {
|
||||
minX: true,
|
||||
minY: true,
|
||||
@@ -104,16 +80,22 @@ const PathAttributes = merge({
|
||||
}
|
||||
}, RenderableAttributes);
|
||||
|
||||
const TextAttributes = merge({
|
||||
alignment: true,
|
||||
frame: {
|
||||
diff: fontAndLinesDiffer
|
||||
},
|
||||
path: {
|
||||
diff: arrayDiffer
|
||||
}
|
||||
const FontAttributes = merge({
|
||||
fontFamily: true,
|
||||
fontSize: true,
|
||||
fontWeight: true,
|
||||
fontStyle: true
|
||||
}, RenderableAttributes);
|
||||
|
||||
const TSpanAttributes = merge({
|
||||
line: true
|
||||
}, FontAttributes);
|
||||
|
||||
|
||||
const TextAttributes = merge({
|
||||
alignment: true
|
||||
}, FontAttributes);
|
||||
|
||||
const ClipPathAttributes = {
|
||||
name: true
|
||||
};
|
||||
@@ -184,6 +166,7 @@ const RectAttributes = merge({
|
||||
export {
|
||||
PathAttributes,
|
||||
TextAttributes,
|
||||
TSpanAttributes,
|
||||
GroupAttributes,
|
||||
ClipPathAttributes,
|
||||
CircleAttributes,
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import extractSpan from './extractSpan';
|
||||
import extractTextContent from './extractTextContent';
|
||||
|
||||
export default function (props) {
|
||||
let {children, line} = props;
|
||||
let extractedProps = extractSpan(props);
|
||||
|
||||
if (typeof children === 'string') {
|
||||
line = children;
|
||||
children = null;
|
||||
} else {
|
||||
children = extractTextContent(props.children);
|
||||
line = null;
|
||||
}
|
||||
console.log(extractedProps);
|
||||
return {
|
||||
...extractedProps,
|
||||
children,
|
||||
line
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,76 @@
|
||||
import React, {
|
||||
Children
|
||||
} from 'react';
|
||||
|
||||
import TSpan from '../../elements/TSpan';
|
||||
import extractTextContent from './extractTextContent';
|
||||
import SerializablePath from '../SerializablePath';
|
||||
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 = /,/;
|
||||
|
||||
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 parseDelta(delta) {
|
||||
return delta.toString().split(spaceReg);
|
||||
}
|
||||
|
||||
export default function(props) {
|
||||
return {
|
||||
dx: parseDelta(props.dx || ''),
|
||||
dy: parseDelta(props.dy || ''),
|
||||
...extractFont(props)
|
||||
};
|
||||
}
|
||||
+34
-84
@@ -1,93 +1,43 @@
|
||||
import SerializablePath from '../SerializablePath';
|
||||
import _ from 'lodash';
|
||||
const newLine = /\n/g;
|
||||
const defaultFontFamily = '"Helvetica Neue", "Helvetica", Arial';
|
||||
const fontRegExp = /^\s*((?:(?:normal|bold|italic)\s+)*)(?:(\d+(?:\.\d+)?)[ptexm%]*(?:\s*\/.*?)?\s+)?\s*"?([^"]*)/i;
|
||||
const fontFamilyPrefix = /^[\s"']*/;
|
||||
const fontFamilySuffix = /[\s"']*$/;
|
||||
let cachedFontObjectsFromString = {};
|
||||
import extractTextContent from './extractTextContent';
|
||||
import extractSpan from './extractSpan';
|
||||
|
||||
function childrenAsString(children) {
|
||||
if (!children) {
|
||||
return '';
|
||||
}
|
||||
if (typeof children === 'string') {
|
||||
return children;
|
||||
}
|
||||
if (children.length) {
|
||||
return children.join('\n');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function extractFontAndLines(font, text) {
|
||||
return {
|
||||
font: extractFont(font),
|
||||
lines: text.split(newLine)
|
||||
};
|
||||
}
|
||||
|
||||
function extractSingleFontFamily(fontFamilyString = defaultFontFamily) {
|
||||
// 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.split(',')[0]
|
||||
.replace(fontFamilyPrefix, '')
|
||||
.replace(fontFamilySuffix, '');
|
||||
}
|
||||
|
||||
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(font) {
|
||||
if (_.isNil(font)) {
|
||||
return null;
|
||||
}
|
||||
if (typeof font === 'string') {
|
||||
return parseFontString(font);
|
||||
}
|
||||
let fontFamily = extractSingleFontFamily(font.fontFamily);
|
||||
let fontSize = +font.fontSize || 12;
|
||||
|
||||
return {
|
||||
fontFamily: fontFamily,
|
||||
fontSize: fontSize,
|
||||
fontWeight: font.fontWeight,
|
||||
fontStyle: font.fontStyle
|
||||
};
|
||||
}
|
||||
|
||||
const anchord = {
|
||||
const anchors = {
|
||||
end: 1,
|
||||
middle: 2,
|
||||
start: 0
|
||||
};
|
||||
|
||||
export default function(props) {
|
||||
let children = extractTextContent(props.children);
|
||||
let extractedProps = extractSpan(props);
|
||||
let firstSpan = children[0];
|
||||
let alignment;
|
||||
let {dx, dy} = extractedProps;
|
||||
let maxDeltaLength = Math.max(dx.length, dy.length);
|
||||
|
||||
if (firstSpan && firstSpan.props.hasOwnProperty('textAnchor')) {
|
||||
alignment = anchors[firstSpan.props.textAnchor];
|
||||
} else if (anchors[props.textAnchor]) {
|
||||
alignment = anchors[props.textAnchor];
|
||||
}
|
||||
|
||||
if (!alignment) {
|
||||
alignment = 0;
|
||||
}
|
||||
|
||||
for (let i = 0; i < maxDeltaLength; i++) {
|
||||
console.log(i);
|
||||
}
|
||||
|
||||
console.log(extractedProps);
|
||||
|
||||
return {
|
||||
alignment: anchord[props.textAnchor] || 0,
|
||||
frame: extractFontAndLines(
|
||||
props,
|
||||
childrenAsString(props.children)
|
||||
),
|
||||
path: props.path ? new SerializablePath(props.path).toJSON() : undefined
|
||||
};
|
||||
alignment,
|
||||
children,
|
||||
fontFamily: 'Helvetica Neue',
|
||||
fontSize: 12,
|
||||
fontStyle: 'normal',
|
||||
fontWeight: 'normal',
|
||||
...extractedProps
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import React, {
|
||||
Children
|
||||
} from 'react';
|
||||
|
||||
import TSpan from '../../elements/TSpan';
|
||||
const newLine = /\n/g;
|
||||
|
||||
export default function(children) {
|
||||
let spans = [];
|
||||
|
||||
Children.forEach(children, function (child = '') {
|
||||
let span;
|
||||
if (typeof child === 'string') {
|
||||
span = <TSpan>{child.replace(newLine, ' ')}</TSpan>;
|
||||
} else if (child.type === TSpan) {
|
||||
span = child;
|
||||
} else {
|
||||
// give warning about the illegal child type
|
||||
return;
|
||||
}
|
||||
|
||||
spans.push(span);
|
||||
});
|
||||
|
||||
return spans;
|
||||
}
|
||||
Reference in New Issue
Block a user