@@ -514,53 +514,89 @@ protected void parsePath() {
514
514
char [] pathDataChars = pathData .toCharArray ();
515
515
516
516
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 ;
519
528
520
529
for (int i = 0 ; i < pathDataChars .length ; i ++) {
521
530
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.
537
561
pathBuffer .append ("|" );
562
+ lexState = LexState .INTEGER ;
538
563
}
564
+ pathBuffer .append ("-" );
565
+ continue ;
539
566
}
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 ;
542
576
}
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 ;
545
583
}
546
- else if (isOnDecimal && (c < '0' || c > '9' )) {
584
+
585
+ // The following are executed for non-numeral elements
586
+
587
+ if (lexState != LexState .NEUTRAL ) {
547
588
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 ;
556
590
}
591
+
557
592
if (c != ',' ) {
558
- pathBuffer .append (c ); //"" + pathDataBuffer.charAt(i));
593
+ pathBuffer .append (c );
559
594
}
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 ;
562
599
}
563
- lastSeparate = separate ;
564
600
}
565
601
566
602
// use whitespace constant to get rid of extra spaces and CR or LF
0 commit comments