summaryrefslogtreecommitdiffstats
path: root/src/patharray.js
diff options
context:
space:
mode:
authorUlrich-Matthias Schäfer <ulima.ums@googlemail.com>2015-11-18 01:16:41 +0100
committerUlrich-Matthias Schäfer <ulima.ums@googlemail.com>2015-11-18 01:16:41 +0100
commitcf783fca1213d26b50bc07af0ca7e2b0f6385401 (patch)
tree4e619e160e7889d7c9c9abd9d8d4c7617d3c8f43 /src/patharray.js
parent7af9d16adff245c987eaed5ccac40f4d2824d2f3 (diff)
downloadsvg.js-cf783fca1213d26b50bc07af0ca7e2b0f6385401.tar.gz
svg.js-cf783fca1213d26b50bc07af0ca7e2b0f6385401.zip
`SvgPathSeg` is removed in Chrome 48. Added workaround (fixes #409)
Diffstat (limited to 'src/patharray.js')
-rw-r--r--src/patharray.js181
1 files changed, 104 insertions, 77 deletions
diff --git a/src/patharray.js b/src/patharray.js
index f2a0124..8def341 100644
--- a/src/patharray.js
+++ b/src/patharray.js
@@ -102,97 +102,124 @@ SVG.extend(SVG.PathArray, {
}
// Absolutize and parse path to array
, parse: function(array) {
- // if it's already is a patharray, no need to parse it
+ // if it's already a patharray, no need to parse it
if (array instanceof SVG.PathArray) return array.valueOf()
- // prepare for parsing
- var i, il, x0, y0, x1, y1, x2, y2, s, seg, segs
+ // prepare for parsing
+ var i, x0, y0, s, seg, arr
, x = 0
, y = 0
+ , paramCnt = { 'M':2, 'L':2, 'H':1, 'V':1, 'C':6, 'S':4, 'Q':4, 'T':2, 'A':7 }
+
+ if(typeof array == 'string'){
+
+ array = array
+ .replace(SVG.regex.negExp, 'X') // replace all negative exponents with certain char
+ .replace(SVG.regex.pathLetters, ' $& ') // put some room between letters and numbers
+ .replace(SVG.regex.hyphen, ' -') // add space before hyphen
+ .replace(SVG.regex.comma, ' ') // unify all spaces
+ .replace(SVG.regex.X, 'e-') // add back the expoent
+ .trim() // trim
+ .split(SVG.regex.whitespaces) // split into array
+
+ }else{
+ array = array.reduce(function(prev, curr){
+ return [].concat.apply(prev, curr)
+ }, [])
+ }
- // populate working path
- SVG.parser.path.setAttribute('d', typeof array === 'string' ? array : arrayToString(array))
-
- // get segments
- segs = SVG.parser.path.pathSegList
-
- for (i = 0, il = segs.numberOfItems; i < il; ++i) {
- seg = segs.getItem(i)
- s = seg.pathSegTypeAsLetter
-
- // yes, this IS quite verbose but also about 30 times faster than .test() with a precompiled regex
- if (s == 'M' || s == 'L' || s == 'H' || s == 'V' || s == 'C' || s == 'S' || s == 'Q' || s == 'T' || s == 'A') {
- if ('x' in seg) x = seg.x
- if ('y' in seg) y = seg.y
-
- } else {
- if ('x1' in seg) x1 = x + seg.x1
- if ('x2' in seg) x2 = x + seg.x2
- if ('y1' in seg) y1 = y + seg.y1
- if ('y2' in seg) y2 = y + seg.y2
- if ('x' in seg) x += seg.x
- if ('y' in seg) y += seg.y
-
- if (s == 'm')
- segs.replaceItem(SVG.parser.path.createSVGPathSegMovetoAbs(x, y), i)
- else if (s == 'l')
- segs.replaceItem(SVG.parser.path.createSVGPathSegLinetoAbs(x, y), i)
- else if (s == 'h')
- segs.replaceItem(SVG.parser.path.createSVGPathSegLinetoHorizontalAbs(x), i)
- else if (s == 'v')
- segs.replaceItem(SVG.parser.path.createSVGPathSegLinetoVerticalAbs(y), i)
- else if (s == 'c')
- segs.replaceItem(SVG.parser.path.createSVGPathSegCurvetoCubicAbs(x, y, x1, y1, x2, y2), i)
- else if (s == 's')
- segs.replaceItem(SVG.parser.path.createSVGPathSegCurvetoCubicSmoothAbs(x, y, x2, y2), i)
- else if (s == 'q')
- segs.replaceItem(SVG.parser.path.createSVGPathSegCurvetoQuadraticAbs(x, y, x1, y1), i)
- else if (s == 't')
- segs.replaceItem(SVG.parser.path.createSVGPathSegCurvetoQuadraticSmoothAbs(x, y), i)
- else if (s == 'a')
- segs.replaceItem(SVG.parser.path.createSVGPathSegArcAbs(x, y, seg.r1, seg.r2, seg.angle, seg.largeArcFlag, seg.sweepFlag), i)
- else if (s == 'z' || s == 'Z') {
- x = x0
- y = y0
+ // array now is an array containing all parts of a path e.g. ['M', '0', '0', 'L', '30', '30' ...]
+
+ var arr = []
+
+ do{
+
+ // Test if we have a path letter
+ if(SVG.regex.isPathLetter.test(array[0])){
+ s = array[0]
+ array.shift()
+ // If last letter was a move command and we got no new, it defaults to [L]ine
+ }else if(s.toUpperCase() == 'M'){
+ s = 'L'
+ }
+
+ // add path letter as first element
+ seg = [s.toUpperCase()]
+
+ // push all necessary parameters to segment
+ for(i = 0; i < paramCnt[seg[0]]; ++i){
+ seg.push(parseFloat(array.shift()))
+ }
+
+ // upper case
+ if(s == seg[0]){
+
+ if(s == 'M' || s == 'L' || s == 'C' || s == 'Q'){
+ x = seg[paramCnt[seg[0]]-1]
+ y = seg[paramCnt[seg[0]]]
+ }else if(s == 'V'){
+ y = seg[1]
+ }else if(s == 'H'){
+ x = seg[1]
+ }else if(s == 'A'){
+ x = seg[6]
+ y = seg[7]
}
+
+ // lower case
+ }else{
+
+ // convert relative to absolute values
+ if(s == 'm' || s == 'l' || s == 'c' || s == 's' || s == 'q' || s == 't'){
+
+ seg[1] += x
+ seg[2] += y
+
+ if(seg[3] != null){
+ seg[3] += x
+ seg[4] += y
+ }
+
+ if(seg[5] != null){
+ seg[5] += x
+ seg[6] += y
+ }
+
+ // move pointer
+ x = seg[paramCnt[seg[0]]-1]
+ y = seg[paramCnt[seg[0]]]
+
+ }else if(s == 'v'){
+ seg[1] += y
+ y = seg[1]
+ }else if(s == 'h'){
+ seg[1] += x
+ x = seg[1]
+ }else if(s == 'a'){
+ seg[6] += x
+ seg[7] += y
+ x = seg[6]
+ y = seg[7]
+ }
+
}
- // record the start of a subpath
- if (s == 'M' || s == 'm') {
+ if(seg[0] == 'M'){
x0 = x
y0 = y
}
- }
- // build internal representation
- array = []
- segs = SVG.parser.path.pathSegList
+ if(seg[0] == 'Z'){
+ x = x0
+ y = y0
+ }
+
+ arr.push(seg)
+
+ }while(array.length)
- for (i = 0, il = segs.numberOfItems; i < il; ++i) {
- seg = segs.getItem(i)
- s = seg.pathSegTypeAsLetter
- x = [s]
-
- if (s == 'M' || s == 'L' || s == 'T')
- x.push(seg.x, seg.y)
- else if (s == 'H')
- x.push(seg.x)
- else if (s == 'V')
- x.push(seg.y)
- else if (s == 'C')
- x.push(seg.x1, seg.y1, seg.x2, seg.y2, seg.x, seg.y)
- else if (s == 'S')
- x.push(seg.x2, seg.y2, seg.x, seg.y)
- else if (s == 'Q')
- x.push(seg.x1, seg.y1, seg.x, seg.y)
- else if (s == 'A')
- x.push(seg.r1, seg.r2, seg.angle, seg.largeArcFlag | 0, seg.sweepFlag | 0, seg.x, seg.y)
-
- // store segment
- array.push(x)
- }
+ return arr
- return array
}
// Get bounding box of path
, bbox: function() {