@@ -3,9 +3,12 @@ package com.opensource.svgaplayer
3
3
import android.graphics.Path
4
4
import java.util.*
5
5
6
- val VALID_METHODS : List <String > = listOf (" M" , " L" , " H" , " V" , " C" , " S" , " Q" , " R" , " A" , " Z" , " m" , " l" , " h" , " v" , " c" , " s" , " q" , " r" , " a" , " z" )
6
+ private val VALID_METHODS : Set <String > = setOf (" M" , " L" , " H" , " V" , " C" , " S" , " Q" , " R" , " A" , " Z" , " m" , " l" , " h" , " v" , " c" , " s" , " q" , " r" , " a" , " z" )
7
+ private val regex = " ([a-zA-Z])" .toRegex()
7
8
8
- class SVGAPath (private val strValue : String ) {
9
+ class SVGAPath (originValue : String ) {
10
+
11
+ private val replacedValue: String = originValue.replace(regex, " |||$1 " ).replace(" ," , " " )
9
12
10
13
private var cachedPath: Path ? = null
11
14
@@ -15,78 +18,76 @@ class SVGAPath(private val strValue: String) {
15
18
return
16
19
}
17
20
val cachedPath = Path ()
18
- var currentMethod = " "
19
- val args = ArrayList <SVGAPoint >()
20
- var argLast: String? = null
21
- val items = strValue.split(" [,\\ s+]" .toRegex()).dropLastWhile(String ::isEmpty).toTypedArray()
22
- for (item in items) {
23
- if (item.isEmpty()) {
24
- continue
25
- }
26
- val firstLetter = item.substring(0 , 1 )
21
+ val segments = StringTokenizer (this .replacedValue, " |||" )
22
+ while (segments.hasMoreTokens()) {
23
+ val segment = segments.nextToken()
24
+ if (segment.isEmpty()) { continue }
25
+ val firstLetter = segment.substring(0 , 1 )
27
26
if (VALID_METHODS .contains(firstLetter)) {
28
- argLast?.takeIf { it.isNotEmpty() }?.let {
29
- args.add(SVGAPoint (0.0f , 0.0f , try {it.toFloat()} catch (e: Exception ) { 0.0f }))
30
- }
31
- this .operate(cachedPath, currentMethod, args)
32
- args.clear()
33
- currentMethod = firstLetter
34
- argLast = item.substring(1 )
35
- } else {
36
- argLast = if (null != argLast && argLast.trim { it <= ' ' }.isNotEmpty()) {
37
- args.add(SVGAPoint (try {
38
- argLast.toFloat()
39
- } catch (e: Exception ) {0.0f }, try {
40
- item.toFloat()
41
- } catch (e: Exception ) {0.0f }, 0.0f ))
42
- null
43
- } else {
44
- item
45
- }
27
+ operate(cachedPath, firstLetter, StringTokenizer (segment.substring(1 ).trim(), " " ))
46
28
}
47
29
}
48
- this .operate(cachedPath, currentMethod, args)
49
30
this .cachedPath = cachedPath
50
31
toPath.addPath(cachedPath)
51
32
}
52
33
53
- private fun operate (finalPath : Path , method : String , args : List <SVGAPoint >) {
34
+ private fun operate (finalPath : Path , method : String , args : StringTokenizer ) {
35
+ var x0 = 0.0f
36
+ var y0 = 0.0f
37
+ var x1 = 0.0f
38
+ var y1 = 0.0f
39
+ var x2 = 0.0f
40
+ var y2 = 0.0f
41
+ try {
42
+ var index = 0
43
+ while (args.hasMoreTokens()) {
44
+ val s = args.nextToken()
45
+ if (index == 0 ) { x0 = s.toFloat() }
46
+ if (index == 1 ) { y0 = s.toFloat() }
47
+ if (index == 2 ) { x1 = s.toFloat() }
48
+ if (index == 3 ) { y1 = s.toFloat() }
49
+ if (index == 4 ) { x2 = s.toFloat() }
50
+ if (index == 5 ) { y2 = s.toFloat() }
51
+ index++
52
+ }
53
+ } catch (e: Exception ) {}
54
54
var currentPoint = SVGAPoint (0.0f , 0.0f , 0.0f )
55
- if (method == " M" && args.size == 1 ) {
56
- finalPath.moveTo(args[ 0 ].x, args[ 0 ].y )
57
- currentPoint = SVGAPoint (args[ 0 ].x, args[ 0 ].y , 0.0f )
58
- } else if (method == " m" && args.size == 1 ) {
59
- finalPath.rMoveTo(args[ 0 ].x, args[ 0 ].y )
60
- currentPoint = SVGAPoint (currentPoint.x + args[ 0 ].x , currentPoint.y + args[ 0 ].y , 0.0f )
55
+ if (method == " M" ) {
56
+ finalPath.moveTo(x0, y0 )
57
+ currentPoint = SVGAPoint (x0, y0 , 0.0f )
58
+ } else if (method == " m" ) {
59
+ finalPath.rMoveTo(x0, y0 )
60
+ currentPoint = SVGAPoint (currentPoint.x + x0 , currentPoint.y + y0 , 0.0f )
61
61
}
62
- if (method == " L" && args.size == 1 ) {
63
- finalPath.lineTo(args[ 0 ].x, args[ 0 ].y )
64
- } else if (method == " l" && args.size == 1 ) {
65
- finalPath.rLineTo(args[ 0 ].x, args[ 0 ].y )
62
+ if (method == " L" ) {
63
+ finalPath.lineTo(x0, y0 )
64
+ } else if (method == " l" ) {
65
+ finalPath.rLineTo(x0, y0 )
66
66
}
67
- if (method == " C" && args.size == 3 ) {
68
- finalPath.cubicTo(args[ 0 ].x, args[ 0 ].y, args[ 1 ].x, args[ 1 ].y, args[ 2 ].x, args[ 2 ].y )
69
- } else if (method == " c" && args.size == 3 ) {
70
- finalPath.rCubicTo(args[ 0 ].x, args[ 0 ].y, args[ 1 ].x, args[ 1 ].y, args[ 2 ].x, args[ 2 ].y )
67
+ if (method == " C" ) {
68
+ finalPath.cubicTo(x0, y0, x1, y1, x2, y2 )
69
+ } else if (method == " c" ) {
70
+ finalPath.rCubicTo(x0, y0, x1, y1, x2, y2 )
71
71
}
72
- if (method == " Q" && args.size == 2 ) {
73
- finalPath.quadTo(args[ 0 ].x, args[ 0 ].y, args[ 1 ].x, args[ 1 ].y )
74
- } else if (method == " q" && args.size == 2 ) {
75
- finalPath.rQuadTo(args[ 0 ].x, args[ 0 ].y, args[ 1 ].x, args[ 1 ].y )
72
+ if (method == " Q" ) {
73
+ finalPath.quadTo(x0, y0, x1, y1 )
74
+ } else if (method == " q" ) {
75
+ finalPath.rQuadTo(x0, y0, x1, y1 )
76
76
}
77
- if (method == " H" && args.size == 1 ) {
78
- finalPath.lineTo(args[ 0 ].value , currentPoint.y)
79
- } else if (method == " h" && args.size == 1 ) {
80
- finalPath.rLineTo(args[ 0 ].value , 0f )
77
+ if (method == " H" ) {
78
+ finalPath.lineTo(x0 , currentPoint.y)
79
+ } else if (method == " h" ) {
80
+ finalPath.rLineTo(x0 , 0f )
81
81
}
82
- if (method == " V" && args.size == 1 ) {
83
- finalPath.lineTo(currentPoint.x, args[ 0 ].value )
84
- } else if (method == " v" && args.size == 1 ) {
85
- finalPath.rLineTo(0f , args[ 0 ].value )
82
+ if (method == " V" ) {
83
+ finalPath.lineTo(currentPoint.x, x0 )
84
+ } else if (method == " v" ) {
85
+ finalPath.rLineTo(0f , x0 )
86
86
}
87
- if (method == " Z" && args.size == 1 ) {
87
+ if (method == " Z" ) {
88
88
finalPath.close()
89
- } else if (method == " z" && args.size == 1 ) {
89
+ }
90
+ else if (method == " z" ) {
90
91
finalPath.close()
91
92
}
92
93
}
0 commit comments