Skip to content

Commit

Permalink
Merge pull request #21195 from Mugen87/dev43
Browse files Browse the repository at this point in the history
SVGLoader: New parseFloats() implementation.
  • Loading branch information
mrdoob committed Feb 3, 2021
2 parents 5388df3 + a81e7b7 commit 05ce38f
Show file tree
Hide file tree
Showing 2 changed files with 424 additions and 24 deletions.
224 changes: 212 additions & 12 deletions examples/js/loaders/SVGLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -973,35 +973,235 @@ THREE.SVGLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype

}

function parseFloats( string ) {
// from https://github.com/ppvg/svg-numbers (MIT License)

var array = string.split( /[\s,]+|(?=\s?[+\-])/ );
function parseFloats( input ) {

for ( var i = 0; i < array.length; i ++ ) {
if ( typeof input !== 'string' ) {

var number = array[ i ];
throw new TypeError( 'Invalid input: ' + typeof input );

// Handle values like 48.6037.7.8
// TODO Find a regex for this
}

// Character groups
var RE = {
SEPARATOR: /[ \t\r\n\,.\-+]/,
WHITESPACE: /[ \t\r\n]/,
DIGIT: /[\d]/,
SIGN: /[-+]/,
POINT: /\./,
COMMA: /,/,
EXP: /e/i
};

// States
var SEP = 0;
var INT = 1;
var FLOAT = 2;
var EXP = 3;

var state = SEP;
var seenComma = true;
var result = [], number = '', exponent = '';

function throwSyntaxError( current, i, partial ) {

var error = new SyntaxError( 'Unexpected character "' + current + '" at index ' + i + '.' );
error.partial = partial;
throw error;

}

function newNumber() {

if ( number !== '' ) {

if ( exponent === '' ) result.push( Number( number ) );
else result.push( Number( number ) * Math.pow( 10, Number( exponent ) ) );

}

number = '';
exponent = '';

}

var current, i = 0, length = input.length;
for ( i = 0; i < length; i ++ ) {

current = input[ i ];

// parse until next number
if ( state === SEP ) {

// eat whitespace
if ( RE.WHITESPACE.test( current ) ) {

continue;

}

// start new number
if ( RE.DIGIT.test( current ) || RE.SIGN.test( current ) ) {

state = INT;
number = current;
continue;

}

if ( RE.POINT.test( current ) ) {

state = FLOAT;
number = current;
continue;

}

// throw on double commas (e.g. "1, , 2")
if ( RE.COMMA.test( current ) ) {

if ( seenComma ) {

throwSyntaxError( current, i, result );

}

seenComma = true;

}

}

// parse integer part
if ( state === INT ) {

if ( RE.DIGIT.test( current ) ) {

number += current;
continue;

}

if ( RE.POINT.test( current ) ) {

number += current;
state = FLOAT;
continue;

}

if ( RE.EXP.test( current ) ) {

if ( number.indexOf( '.' ) !== number.lastIndexOf( '.' ) ) {
state = EXP;
continue;

var split = number.split( '.' );
}

// throw on double signs ("-+1"), but not on sign as separator ("-1-2")
if ( RE.SIGN.test( current )
&& number.length === 1
&& RE.SIGN.test( number[ 0 ] ) ) {

throwSyntaxError( current, i, result );

}

}

// parse decimal part
if ( state === FLOAT ) {

if ( RE.DIGIT.test( current ) ) {

number += current;
continue;

}

for ( var s = 2; s < split.length; s ++ ) {
if ( RE.EXP.test( current ) ) {

array.splice( i + s - 1, 0, '0.' + split[ s ] );
state = EXP;
continue;

}

// throw on double decimal points (e.g. "1..2")
if ( RE.POINT.test( current ) && number[ number.length - 1 ] === '.' ) {

throwSyntaxError( current, i, result );

}

}

array[ i ] = parseFloatWithUnits( number );
// parse exponent part
if ( state == EXP ) {

if ( RE.DIGIT.test( current ) ) {

exponent += current;
continue;

}

if ( RE.SIGN.test( current ) ) {

if ( exponent === '' ) {

exponent += current;
continue;

}

if ( exponent.length === 1 && RE.SIGN.test( exponent ) ) {

throwSyntaxError( current, i, result );

}

}

}


// end of number
if ( RE.WHITESPACE.test( current ) ) {

newNumber();
state = SEP;
seenComma = false;

} else if ( RE.COMMA.test( current ) ) {

newNumber();
state = SEP;
seenComma = true;

} else if ( RE.SIGN.test( current ) ) {

newNumber();
state = INT;
number = current;

} else if ( RE.POINT.test( current ) ) {

newNumber();
state = FLOAT;
number = current;

} else {

throwSyntaxError( current, i, result );

}

}

return array;
// add the last number found (if any)
newNumber();

return result;

}

Expand Down
Loading

0 comments on commit 05ce38f

Please sign in to comment.