@@ -514,53 +514,86 @@ protected void parsePath() {
514514 char [] pathDataChars = pathData .toCharArray ();
515515
516516 StringBuilder pathBuffer = new StringBuilder ();
517- boolean lastSeparate = false ;
518- boolean isOnDecimal = false ;
517+
518+ /*
519+ * The state of the lexer:
520+ * -1: just after the command (i.e. a single alphabet)
521+ * 0: neutral state
522+ * 1: on a digit sequence for integer representation
523+ * 2: on a decimal
524+ * 3: on a digit or a sign in exponent in scientific notation, e.g. 3.14e-2)
525+ * 4: on a digit sequence in exponent
526+ */
527+ int lexState = 0 ;
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 == -1 ) {
534+ pathBuffer .append ("|" );
535+ lexState = 0 ;
536+ }
537+
538+ if (c >= '0' && c <= '9' ) {
539+ if (lexState == 0 || lexState == 3 ) {
540+ // If it is a head of a number representation, enter the 'inside' of the digit sequence.
541+ ++lexState ;
542+ }
543+ pathBuffer .append (c );
544+ continue ;
545+ }
546+
547+ if (c == '-' ) {
548+ if (lexState == 0 ) {
549+ // In neutral state, enter 'digit sequence'.
550+ lexState = 1 ;
551+ }
552+ else if (lexState == 3 ) {
553+ // In the begining of an exponent, enter 'exponent digit sequence'.
554+ lexState = 4 ;
555+ }
556+ else {
557+ // Otherwise, begin a new number representation.
537558 pathBuffer .append ("|" );
559+ lexState = 1 ;
538560 }
561+ pathBuffer .append ("-" );
562+ continue ;
539563 }
540- if (c == 'Z' || c == 'z' ) {
541- separate = false ;
564+
565+ if (c == '.' ) {
566+ if (lexState >= 2 ) {
567+ // Begin a new decimal number unless it is in a neutral state or after a digit sequence
568+ pathBuffer .append ("|" );
569+ }
570+ pathBuffer .append ("." );
571+ lexState = 2 ;
572+ continue ;
542573 }
543- if (c == '.' && !isOnDecimal ) {
544- isOnDecimal = true ;
574+
575+ if (c == 'e' || c == 'E' ) {
576+ // Found 'e' or 'E', enter the 'exponent' state immediately.
577+ pathBuffer .append ("e" );
578+ lexState = 3 ;
579+ continue ;
545580 }
546- else if (isOnDecimal && (c < '0' || c > '9' )) {
581+
582+ // The following are executed for non-numeral elements
583+
584+ if (lexState != 0 ) {
547585 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- }
586+ lexState = 0 ;
556587 }
588+
557589 if (c != ',' ) {
558- pathBuffer .append (c ); //"" + pathDataBuffer.charAt(i));
590+ pathBuffer .append (c );
559591 }
560- if (separate && c != ',' && c != '-' ) {
561- pathBuffer .append ("|" );
592+
593+ if ((c >= 'A' && c <= 'Z' ) || (c >= 'a' && c <= 'z' )) {
594+ // Every alphabet character except for 'e' and 'E' are considered as a command.
595+ lexState = -1 ;
562596 }
563- lastSeparate = separate ;
564597 }
565598
566599 // use whitespace constant to get rid of extra spaces and CR or LF
0 commit comments