@@ -514,53 +514,89 @@ protected void parsePath() {
514514 char [] pathDataChars = pathData .toCharArray ();
515515
516516 StringBuilder pathBuffer = new StringBuilder ();
517- boolean lastSeparate = false ;
518- boolean isOnDecimal = false ;
517+
518+ // The states of the lexical sanner
519+ enum LexState {
520+ AFTER_CMD ,// Just after a command (i.e. a single alphabet)
521+ NEUTRAL , // Neutral state, waiting for a number expression or a command
522+ INTEGER , // On a sequence of digits possibly led by the '-' sign
523+ DECIMAL , // On a digit sequence following the decimal point '.'
524+ EXP_HEAD , // On the head of the exponent part of a scientific notation; the '-' sign or a digit
525+ EXP_TAIL , // On the integer expression in the exponent part
526+ }
527+ LexState lexState = LexState .NEUTRAL ;
519528
520529 for (int i = 0 ; i < pathDataChars .length ; i ++) {
521530 char c = pathDataChars [i ];
522- boolean separate = false ;
523-
524- if (c == 'M' || c == 'm' ||
525- c == 'L' || c == 'l' ||
526- c == 'H' || c == 'h' ||
527- c == 'V' || c == 'v' ||
528- c == 'C' || c == 'c' || // beziers
529- c == 'S' || c == 's' ||
530- c == 'Q' || c == 'q' || // quadratic beziers
531- c == 'T' || c == 't' ||
532- c == 'A' || c == 'a' || // elliptical arc
533- c == 'Z' || c == 'z' || // closepath
534- c == ',' ) {
535- separate = true ;
536- if (i != 0 ) {
531+
532+ // Put a separator after a command.
533+ if (lexState == LexState .AFTER_CMD ) {
534+ pathBuffer .append ("|" );
535+ lexState = LexState .NEUTRAL ;
536+ }
537+
538+ if (c >= '0' && c <= '9' ) {
539+ // If it is a head of a number representation, enter the 'inside' of the digit sequence.
540+ if (lexState == LexState .NEUTRAL ) {
541+ lexState = LexState .INTEGER ;
542+ }
543+ else if (lexState == LexState .EXP_HEAD ) {
544+ lexState = LexState .EXP_TAIL ;
545+ }
546+ pathBuffer .append (c );
547+ continue ;
548+ }
549+
550+ if (c == '-' ) {
551+ if (lexState == LexState .NEUTRAL ) {
552+ // In neutral state, enter 'digit sequence'.
553+ lexState = LexState .INTEGER ;
554+ }
555+ else if (lexState == LexState .EXP_HEAD ) {
556+ // In the begining of an exponent, enter 'exponent digit sequence'.
557+ lexState = LexState .EXP_TAIL ;
558+ }
559+ else {
560+ // Otherwise, begin a new number representation.
537561 pathBuffer .append ("|" );
562+ lexState = LexState .INTEGER ;
538563 }
564+ pathBuffer .append ("-" );
565+ continue ;
539566 }
540- if (c == 'Z' || c == 'z' ) {
541- separate = false ;
567+
568+ if (c == '.' ) {
569+ if (lexState == LexState .DECIMAL || lexState == LexState .EXP_HEAD || lexState == LexState .EXP_TAIL ) {
570+ // Begin a new decimal number unless it is in a neutral state or after a digit sequence
571+ pathBuffer .append ("|" );
572+ }
573+ pathBuffer .append ("." );
574+ lexState = LexState .DECIMAL ;
575+ continue ;
542576 }
543- if (c == '.' && !isOnDecimal ) {
544- isOnDecimal = true ;
577+
578+ if (c == 'e' || c == 'E' ) {
579+ // Found 'e' or 'E', enter the 'exponent' state immediately.
580+ pathBuffer .append ("e" );
581+ lexState = LexState .EXP_HEAD ;
582+ continue ;
545583 }
546- else if (isOnDecimal && (c < '0' || c > '9' )) {
584+
585+ // The following are executed for non-numeral elements
586+
587+ if (lexState != LexState .NEUTRAL ) {
547588 pathBuffer .append ("|" );
548- isOnDecimal = c == '.' ;
549- }
550- if (c == '-' && !lastSeparate ) {
551- // allow for 'e' notation in numbers, e.g. 2.10e-9
552- // https://download.processing.org/bugzilla/1408.html
553- if (i == 0 || pathDataChars [i -1 ] != 'e' ) {
554- pathBuffer .append ("|" );
555- }
589+ lexState = LexState .NEUTRAL ;
556590 }
591+
557592 if (c != ',' ) {
558- pathBuffer .append (c ); //"" + pathDataBuffer.charAt(i));
593+ pathBuffer .append (c );
559594 }
560- if (separate && c != ',' && c != '-' ) {
561- pathBuffer .append ("|" );
595+
596+ if ((c >= 'A' && c <= 'Z' ) || (c >= 'a' && c <= 'z' )) {
597+ // Every alphabet character except for 'e' and 'E' are considered as a command.
598+ lexState = LexState .AFTER_CMD ;
562599 }
563- lastSeparate = separate ;
564600 }
565601
566602 // use whitespace constant to get rid of extra spaces and CR or LF
0 commit comments