@jscad/svg-deserializer 2.5.11 → 3.0.1-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -240
- package/LICENSE +1 -1
- package/README.md +5 -1
- package/dist/jscad-svg-deserializer.es.js +38 -0
- package/dist/jscad-svg-deserializer.min.js +38 -0
- package/package.json +24 -13
- package/rollup.config.js +29 -0
- package/src/constants.js +6 -15
- package/src/helpers.js +11 -24
- package/src/index.js +27 -37
- package/src/shapesMapGeometry.js +42 -42
- package/src/shapesMapJscad.js +37 -39
- package/src/svgElementHelpers.js +16 -31
- package/tests/inkscape.test.js +5 -7
- package/tests/instantiate.test.js +103 -84
- package/tests/issue.1135.test.js +3 -3
- package/tests/issue.885.test.js +5 -9
- package/tests/translate.test.js +59 -63
package/src/helpers.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
import { inchMM, ptMM, pcMM, svgColors } from './constants.js'
|
|
2
2
|
|
|
3
3
|
// Calculate the CAG length/size from the given SVG value (float)
|
|
4
|
-
const svg2cag = (vec, svgUnitsPmm) => [
|
|
4
|
+
export const svg2cag = (vec, svgUnitsPmm) => [
|
|
5
5
|
vec[0] / svgUnitsPmm[0],
|
|
6
6
|
0 - vec[1] / svgUnitsPmm[1]
|
|
7
7
|
]
|
|
8
8
|
|
|
9
9
|
// Calculate the CAG length/size from the given CSS value (string)
|
|
10
|
-
const cagLengthX = (css, svgUnitsPmm, svgUnitsX) => {
|
|
10
|
+
export const cagLengthX = (css, svgUnitsPmm, svgUnitsX) => {
|
|
11
11
|
if (css.indexOf('%') < 0) {
|
|
12
12
|
return css2cag(css, svgUnitsPmm[0])
|
|
13
13
|
}
|
|
@@ -21,7 +21,7 @@ const cagLengthX = (css, svgUnitsPmm, svgUnitsX) => {
|
|
|
21
21
|
return Math.round(v * 100000) / 100000
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
const cagLengthY = (css, svgUnitsPmm, svgUnitsY) => {
|
|
24
|
+
export const cagLengthY = (css, svgUnitsPmm, svgUnitsY) => {
|
|
25
25
|
if (css.indexOf('%') < 0) {
|
|
26
26
|
return css2cag(css, svgUnitsPmm[1])
|
|
27
27
|
}
|
|
@@ -35,7 +35,7 @@ const cagLengthY = (css, svgUnitsPmm, svgUnitsY) => {
|
|
|
35
35
|
return Math.round(v * 100000) / 100000
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
const cagLengthP = (css, svgUnitsPmm, svgUnitsV) => {
|
|
38
|
+
export const cagLengthP = (css, svgUnitsPmm, svgUnitsV) => {
|
|
39
39
|
if (css.indexOf('%') < 0) {
|
|
40
40
|
return css2cag(css, svgUnitsPmm[1])
|
|
41
41
|
}
|
|
@@ -49,7 +49,7 @@ const cagLengthP = (css, svgUnitsPmm, svgUnitsV) => {
|
|
|
49
49
|
return v
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
const css2cag = (css, unit) => {
|
|
52
|
+
export const css2cag = (css, unit) => {
|
|
53
53
|
let v = parseFloat(css) // number part
|
|
54
54
|
if (isNaN(v)) { return 0.0 }
|
|
55
55
|
if (v === 0) return v
|
|
@@ -80,7 +80,7 @@ const css2cag = (css, unit) => {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
// convert the SVG color specification to CAG RGB
|
|
83
|
-
const cagColor = (value) => {
|
|
83
|
+
export const cagColor = (value) => {
|
|
84
84
|
// let rgb = [0,0,0]; // default is black
|
|
85
85
|
let rgb
|
|
86
86
|
value = value.toLowerCase()
|
|
@@ -124,7 +124,7 @@ const cagColor = (value) => {
|
|
|
124
124
|
return rgb
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
const cssStyle = (element, name) => {
|
|
127
|
+
export const cssStyle = (element, name) => {
|
|
128
128
|
if ('style' in element) {
|
|
129
129
|
const list = element.style + ';'
|
|
130
130
|
const pat = name + '\\s*:\\s*(\\S+);'
|
|
@@ -141,7 +141,7 @@ const cssStyle = (element, name) => {
|
|
|
141
141
|
return undefined
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
const reflect = (x, y, px, py) => {
|
|
144
|
+
export const reflect = (x, y, px, py) => {
|
|
145
145
|
const ox = x - px
|
|
146
146
|
const oy = y - py
|
|
147
147
|
if (x === px && y === px) return [x, y]
|
|
@@ -151,7 +151,7 @@ const reflect = (x, y, px, py) => {
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
// Return the value for the given attribute from the group hiearchy
|
|
154
|
-
const groupValue = (svgGroups, name) => {
|
|
154
|
+
export const groupValue = (svgGroups, name) => {
|
|
155
155
|
let i = svgGroups.length
|
|
156
156
|
while (i > 0) {
|
|
157
157
|
const g = svgGroups[i - 1]
|
|
@@ -163,7 +163,7 @@ const groupValue = (svgGroups, name) => {
|
|
|
163
163
|
return undefined
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
-
const svgColorForTarget = (target, svgObject) => {
|
|
166
|
+
export const svgColorForTarget = (target, svgObject) => {
|
|
167
167
|
let color = null
|
|
168
168
|
if (target === 'path') {
|
|
169
169
|
if (svgObject.stroke) {
|
|
@@ -185,16 +185,3 @@ const svgColorForTarget = (target, svgObject) => {
|
|
|
185
185
|
}
|
|
186
186
|
return color
|
|
187
187
|
}
|
|
188
|
-
|
|
189
|
-
module.exports = {
|
|
190
|
-
svg2cag,
|
|
191
|
-
cagLengthX,
|
|
192
|
-
cagLengthY,
|
|
193
|
-
cagLengthP,
|
|
194
|
-
css2cag,
|
|
195
|
-
cagColor,
|
|
196
|
-
cssStyle,
|
|
197
|
-
reflect,
|
|
198
|
-
groupValue,
|
|
199
|
-
svgColorForTarget
|
|
200
|
-
}
|
package/src/index.js
CHANGED
|
@@ -1,27 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
## License
|
|
3
|
-
|
|
4
|
-
Copyright (c) 2016 Z3 Development https://github.com/z3dev
|
|
5
|
-
2017 Mark 'kaosat-dev' Moissette
|
|
6
|
-
|
|
7
|
-
The upgrades (direct geometry instantiation from this deserializer) and refactoring
|
|
8
|
-
have been very kindly sponsored by [Copenhagen Fabrication / Stykka](https://www.stykka.com/)
|
|
1
|
+
import saxes from 'saxes'
|
|
9
2
|
|
|
10
|
-
|
|
11
|
-
|
|
3
|
+
import { colorize, mirrorX, mirrorY, rotateZ, translate, scale } from '@jscad/modeling'
|
|
4
|
+
import { toArray } from '@jscad/array-utils'
|
|
5
|
+
import { ensureString } from '@jscad/io-utils'
|
|
12
6
|
|
|
13
|
-
|
|
7
|
+
import { pxPmm } from './constants.js'
|
|
8
|
+
import { cagLengthX, cagLengthY, svgColorForTarget } from './helpers.js'
|
|
9
|
+
import { svgSvg, svgRect, svgCircle, svgGroup, svgLine, svgPath, svgEllipse, svgPolygon, svgPolyline, svgUse } from './svgElementHelpers.js'
|
|
10
|
+
import { shapesMapGeometry } from './shapesMapGeometry.js'
|
|
11
|
+
import { shapesMapJscad } from './shapesMapJscad.js'
|
|
14
12
|
|
|
15
|
-
const {
|
|
16
|
-
const { toArray } = require('@jscad/array-utils')
|
|
17
|
-
const { ensureString } = require('@jscad/io-utils')
|
|
18
|
-
|
|
19
|
-
const version = require('../package.json').version
|
|
20
|
-
|
|
21
|
-
const { cagLengthX, cagLengthY, svgColorForTarget } = require('./helpers')
|
|
22
|
-
const { svgSvg, svgRect, svgCircle, svgGroup, svgLine, svgPath, svgEllipse, svgPolygon, svgPolyline, svgUse } = require('./svgElementHelpers')
|
|
23
|
-
const shapesMapGeometry = require('./shapesMapGeometry')
|
|
24
|
-
const shapesMapJscad = require('./shapesMapJscad')
|
|
13
|
+
const version = '[VI]{version}[/VI]' // version is injected by rollup
|
|
25
14
|
|
|
26
15
|
/**
|
|
27
16
|
* Deserializer of SVG source data to JSCAD geometries.
|
|
@@ -52,15 +41,16 @@ const deserialize = (options, input) => {
|
|
|
52
41
|
addMetaData: true,
|
|
53
42
|
filename: 'svg',
|
|
54
43
|
output: 'script',
|
|
55
|
-
pxPmm
|
|
44
|
+
pxPmm,
|
|
56
45
|
segments: 32,
|
|
57
46
|
target: 'path', // target - 'geom2' or 'path'
|
|
58
47
|
pathSelfClosed: 'error',
|
|
59
48
|
version
|
|
60
49
|
}
|
|
61
50
|
options = Object.assign({}, defaults, options)
|
|
51
|
+
|
|
62
52
|
input = ensureString(input)
|
|
63
|
-
return options.output === 'script' ?
|
|
53
|
+
return options.output === 'script' ? translateScript(input, options) : instantiate(input, options)
|
|
64
54
|
}
|
|
65
55
|
|
|
66
56
|
/*
|
|
@@ -102,7 +92,7 @@ const instantiate = (src, options) => {
|
|
|
102
92
|
* at the start of the file
|
|
103
93
|
* @return {string} a string (JSCAD script)
|
|
104
94
|
*/
|
|
105
|
-
const
|
|
95
|
+
const translateScript = (src, options) => {
|
|
106
96
|
const { filename, version, pxPmm, addMetaData } = options
|
|
107
97
|
|
|
108
98
|
options && options.statusCallback && options.statusCallback({ progress: 0 })
|
|
@@ -194,29 +184,29 @@ const objectify = (options, group) => {
|
|
|
194
184
|
if (scaleAttribute !== null) {
|
|
195
185
|
let x = Math.abs(scaleAttribute.scale[0])
|
|
196
186
|
let y = Math.abs(scaleAttribute.scale[1])
|
|
197
|
-
shape =
|
|
187
|
+
shape = scale([x, y, 1], shape)
|
|
198
188
|
// and mirror if necessary
|
|
199
189
|
x = scaleAttribute.scale[0]
|
|
200
190
|
y = scaleAttribute.scale[1]
|
|
201
191
|
if (x < 0) {
|
|
202
|
-
shape =
|
|
192
|
+
shape = mirrorX(shape)
|
|
203
193
|
}
|
|
204
194
|
if (y < 0) {
|
|
205
|
-
shape =
|
|
195
|
+
shape = mirrorY(shape)
|
|
206
196
|
}
|
|
207
197
|
}
|
|
208
198
|
if (rotateAttribute !== null) {
|
|
209
199
|
const z = 0 - rotateAttribute.rotate * 0.017453292519943295 // radians
|
|
210
|
-
shape =
|
|
200
|
+
shape = rotateZ(z, shape)
|
|
211
201
|
}
|
|
212
202
|
if (translateAttribute !== null) {
|
|
213
203
|
const x = cagLengthX(translateAttribute.translate[0], svgUnitsPmm, svgUnitsX)
|
|
214
204
|
const y = (0 - cagLengthY(translateAttribute.translate[1], svgUnitsPmm, svgUnitsY))
|
|
215
|
-
shape =
|
|
205
|
+
shape = translate([x, y, 0], shape)
|
|
216
206
|
}
|
|
217
207
|
}
|
|
218
208
|
const color = svgColorForTarget(target, obj)
|
|
219
|
-
if (color) shape =
|
|
209
|
+
if (color) shape = colorize(color, shape)
|
|
220
210
|
return shape
|
|
221
211
|
})
|
|
222
212
|
geometries = geometries.concat(shapes)
|
|
@@ -366,7 +356,7 @@ const createSvgParser = (src, pxPmm) => {
|
|
|
366
356
|
// this is just like an embedded SVG but does NOT render directly, only named
|
|
367
357
|
// this requires another set of control objects
|
|
368
358
|
// only add to named objects for later USE
|
|
369
|
-
// break
|
|
359
|
+
// break
|
|
370
360
|
|
|
371
361
|
if (obj) {
|
|
372
362
|
// add to named objects if necessary
|
|
@@ -397,7 +387,7 @@ const createSvgParser = (src, pxPmm) => {
|
|
|
397
387
|
if (svgGroups.length > 0) {
|
|
398
388
|
const group = svgGroups.pop()
|
|
399
389
|
if ('objects' in group) {
|
|
400
|
-
|
|
390
|
+
// TBD apply presentation attributes from the group
|
|
401
391
|
group.objects.push(obj)
|
|
402
392
|
}
|
|
403
393
|
svgGroups.push(group)
|
|
@@ -424,7 +414,7 @@ const createSvgParser = (src, pxPmm) => {
|
|
|
424
414
|
DEFS: () => { svgInDefs = false },
|
|
425
415
|
USE: popGroup,
|
|
426
416
|
G: popGroup,
|
|
427
|
-
undefined: () => {
|
|
417
|
+
undefined: () => {}
|
|
428
418
|
}
|
|
429
419
|
const elementName = node.name.toUpperCase()
|
|
430
420
|
const obj = objMap[elementName] ? objMap[elementName]() : undefined
|
|
@@ -444,9 +434,9 @@ const createSvgParser = (src, pxPmm) => {
|
|
|
444
434
|
return parser
|
|
445
435
|
}
|
|
446
436
|
|
|
447
|
-
const
|
|
437
|
+
const mimeType = 'image/svg+xml'
|
|
448
438
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
439
|
+
export {
|
|
440
|
+
mimeType,
|
|
441
|
+
deserialize
|
|
452
442
|
}
|
package/src/shapesMapGeometry.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { circle, ellipse, geom2, line, path2, rectangle, roundedRectangle } from '@jscad/modeling'
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import { svg2cag, cagLengthX, cagLengthY, cagLengthP, reflect } from './helpers.js'
|
|
4
4
|
|
|
5
|
-
const shapesMapGeometry = (obj, objectify, params) => {
|
|
5
|
+
export const shapesMapGeometry = (obj, objectify, params) => {
|
|
6
6
|
const { svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups, target, segments, pathSelfClosed } = params
|
|
7
7
|
|
|
8
8
|
const types = {
|
|
@@ -21,12 +21,12 @@ const shapesMapGeometry = (obj, objectify, params) => {
|
|
|
21
21
|
x = (x + (w / 2)) // position the object via the center
|
|
22
22
|
y = (y - (h / 2)) // position the object via the center
|
|
23
23
|
if (rx === 0) {
|
|
24
|
-
shape =
|
|
24
|
+
shape = rectangle({ center: [x, y], size: [w, h] })
|
|
25
25
|
} else {
|
|
26
|
-
shape =
|
|
26
|
+
shape = roundedRectangle({ center: [x, y], segments, size: [w, h], roundRadius: rx })
|
|
27
27
|
}
|
|
28
28
|
if (target === 'path') {
|
|
29
|
-
shape =
|
|
29
|
+
shape = path2.fromPoints({ closed: true }, geom2.toPoints(shape))
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
return shape
|
|
@@ -39,9 +39,9 @@ const shapesMapGeometry = (obj, objectify, params) => {
|
|
|
39
39
|
|
|
40
40
|
let shape
|
|
41
41
|
if (r > 0) {
|
|
42
|
-
shape =
|
|
42
|
+
shape = circle({ center: [x, y], segments, radius: r })
|
|
43
43
|
if (target === 'path') {
|
|
44
|
-
shape =
|
|
44
|
+
shape = path2.fromPoints({ closed: true }, geom2.toPoints(shape))
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
return shape
|
|
@@ -55,9 +55,9 @@ const shapesMapGeometry = (obj, objectify, params) => {
|
|
|
55
55
|
|
|
56
56
|
let shape
|
|
57
57
|
if (rx > 0 && ry > 0) {
|
|
58
|
-
shape =
|
|
58
|
+
shape = ellipse({ center: [cx, cy], segments, radius: [rx, ry] })
|
|
59
59
|
if (target === 'path') {
|
|
60
|
-
shape =
|
|
60
|
+
shape = path2.fromPoints({ closed: true }, geom2.toPoints(shape))
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
return shape
|
|
@@ -78,7 +78,7 @@ const shapesMapGeometry = (obj, objectify, params) => {
|
|
|
78
78
|
// }
|
|
79
79
|
// }
|
|
80
80
|
|
|
81
|
-
const shape =
|
|
81
|
+
const shape = line([[x1, y1], [x2, y2]])
|
|
82
82
|
if (target === 'geom2') {
|
|
83
83
|
// TODO expand if 2D target
|
|
84
84
|
}
|
|
@@ -96,9 +96,9 @@ const shapesMapGeometry = (obj, objectify, params) => {
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
if (target === 'geom2') {
|
|
99
|
-
return
|
|
99
|
+
return geom2.create([points])
|
|
100
100
|
}
|
|
101
|
-
return
|
|
101
|
+
return path2.fromPoints({}, points)
|
|
102
102
|
},
|
|
103
103
|
|
|
104
104
|
polyline: (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV) => {
|
|
@@ -121,7 +121,7 @@ const shapesMapGeometry = (obj, objectify, params) => {
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
const shape =
|
|
124
|
+
const shape = line(points)
|
|
125
125
|
if (target === 'geom2') {
|
|
126
126
|
// TODO expand if 2D target
|
|
127
127
|
// .expandToCAG(r, CSG.defaultResolution2D)
|
|
@@ -136,9 +136,8 @@ const shapesMapGeometry = (obj, objectify, params) => {
|
|
|
136
136
|
const shapes = listofentries.map((entry) => {
|
|
137
137
|
const path = entry[1]
|
|
138
138
|
if (target === 'geom2' && path.isClosed) {
|
|
139
|
-
const points =
|
|
140
|
-
|
|
141
|
-
return geometries.geom2.fromPoints(points)
|
|
139
|
+
const points = path2.toPoints(path)
|
|
140
|
+
return geom2.create([points])
|
|
142
141
|
}
|
|
143
142
|
return path
|
|
144
143
|
})
|
|
@@ -149,11 +148,9 @@ const shapesMapGeometry = (obj, objectify, params) => {
|
|
|
149
148
|
return types[obj.type](obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups, segments)
|
|
150
149
|
}
|
|
151
150
|
|
|
152
|
-
module.exports = shapesMapGeometry
|
|
153
|
-
|
|
154
151
|
const appendPoints = (points, geometry) => {
|
|
155
|
-
if (geometry) return
|
|
156
|
-
return
|
|
152
|
+
if (geometry) return path2.appendPoints(points, geometry)
|
|
153
|
+
return path2.fromPoints({ }, points)
|
|
157
154
|
}
|
|
158
155
|
|
|
159
156
|
const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups, segments, pathSelfClosed) => {
|
|
@@ -188,7 +185,9 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
188
185
|
pc = false
|
|
189
186
|
}
|
|
190
187
|
const ensurePath = () => {
|
|
191
|
-
if (!paths[pathName])
|
|
188
|
+
if (!paths[pathName]) {
|
|
189
|
+
paths[pathName] = path2.fromPoints({}, [])
|
|
190
|
+
}
|
|
192
191
|
}
|
|
193
192
|
for (let j = 0; j < obj.commands.length; j++) {
|
|
194
193
|
const co = obj.commands[j]
|
|
@@ -249,7 +248,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
249
248
|
cx = cx + parseFloat(pts[i++])
|
|
250
249
|
cy = cy + parseFloat(pts[i++])
|
|
251
250
|
ensurePath()
|
|
252
|
-
paths[pathName] =
|
|
251
|
+
paths[pathName] = path2.appendArc({
|
|
253
252
|
segments,
|
|
254
253
|
endpoint: svg2cag([cx, cy], svgUnitsPmm),
|
|
255
254
|
radius: svg2cag([rx, ry], svgUnitsPmm),
|
|
@@ -269,7 +268,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
269
268
|
cx = parseFloat(pts[i++])
|
|
270
269
|
cy = parseFloat(pts[i++])
|
|
271
270
|
ensurePath()
|
|
272
|
-
paths[pathName] =
|
|
271
|
+
paths[pathName] = path2.appendArc({
|
|
273
272
|
segments,
|
|
274
273
|
endpoint: svg2cag([cx, cy], svgUnitsPmm),
|
|
275
274
|
radius: svg2cag([rx, ry], svgUnitsPmm),
|
|
@@ -288,7 +287,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
288
287
|
cx = cx + parseFloat(pts[i++])
|
|
289
288
|
cy = cy + parseFloat(pts[i++])
|
|
290
289
|
ensurePath()
|
|
291
|
-
paths[pathName] =
|
|
290
|
+
paths[pathName] = path2.appendBezier({
|
|
292
291
|
segments,
|
|
293
292
|
controlPoints: [
|
|
294
293
|
svg2cag([x1, y1], svgUnitsPmm),
|
|
@@ -310,7 +309,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
310
309
|
cx = parseFloat(pts[i++])
|
|
311
310
|
cy = parseFloat(pts[i++])
|
|
312
311
|
ensurePath()
|
|
313
|
-
paths[pathName] =
|
|
312
|
+
paths[pathName] = path2.appendBezier({
|
|
314
313
|
segments,
|
|
315
314
|
controlPoints: [
|
|
316
315
|
svg2cag([x1, y1], svgUnitsPmm),
|
|
@@ -333,7 +332,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
333
332
|
const q1 = [p0[0] + (2 / 3) * (qx - p0[0]), p0[1] + (2 / 3) * (qy - p0[1])]
|
|
334
333
|
const q2 = [q1[0] + (1 / 3) * (cx - p0[0]), q1[1] + (1 / 3) * (cy - p0[1])]
|
|
335
334
|
ensurePath()
|
|
336
|
-
paths[pathName] =
|
|
335
|
+
paths[pathName] = path2.appendBezier({
|
|
337
336
|
segments,
|
|
338
337
|
controlPoints: [
|
|
339
338
|
svg2cag(q1, svgUnitsPmm),
|
|
@@ -356,7 +355,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
356
355
|
const q1 = [p0[0] + (2 / 3) * (qx - p0[0]), p0[1] + (2 / 3) * (qy - p0[1])]
|
|
357
356
|
const q2 = [q1[0] + (1 / 3) * (cx - p0[0]), q1[1] + (1 / 3) * (cy - p0[1])]
|
|
358
357
|
ensurePath()
|
|
359
|
-
paths[pathName] =
|
|
358
|
+
paths[pathName] = path2.appendBezier({
|
|
360
359
|
segments,
|
|
361
360
|
controlPoints: [
|
|
362
361
|
svg2cag(q1, svgUnitsPmm),
|
|
@@ -377,7 +376,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
377
376
|
const q1 = [p0[0] + (2 / 3) * (qx - p0[0]), p0[1] + (2 / 3) * (qy - p0[1])]
|
|
378
377
|
const q2 = [q1[0] + (1 / 3) * (cx - p0[0]), q1[1] + (1 / 3) * (cy - p0[1])]
|
|
379
378
|
ensurePath()
|
|
380
|
-
paths[pathName] =
|
|
379
|
+
paths[pathName] = path2.appendBezier({
|
|
381
380
|
segments,
|
|
382
381
|
controlPoints: [
|
|
383
382
|
svg2cag(q1, svgUnitsPmm),
|
|
@@ -398,7 +397,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
398
397
|
const q1 = [p0[0] + (2 / 3) * (qx - p0[0]), p0[1] + (2 / 3) * (qy - p0[1])]
|
|
399
398
|
const q2 = [q1[0] + (1 / 3) * (cx - p0[0]), q1[1] + (1 / 3) * (cy - p0[1])]
|
|
400
399
|
ensurePath()
|
|
401
|
-
paths[pathName] =
|
|
400
|
+
paths[pathName] = path2.appendBezier({
|
|
402
401
|
segments,
|
|
403
402
|
controlPoints: [
|
|
404
403
|
svg2cag(q1, svgUnitsPmm),
|
|
@@ -420,13 +419,14 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
420
419
|
cx = cx + parseFloat(pts[i++])
|
|
421
420
|
cy = cy + parseFloat(pts[i++])
|
|
422
421
|
ensurePath()
|
|
423
|
-
paths[pathName] =
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
422
|
+
paths[pathName] = path2.appendBezier({
|
|
423
|
+
segments,
|
|
424
|
+
controlPoints: [
|
|
425
|
+
svg2cag([x1, y1], svgUnitsPmm),
|
|
426
|
+
svg2cag([bx, by], svgUnitsPmm),
|
|
427
|
+
svg2cag([cx, cy], svgUnitsPmm)
|
|
428
|
+
]
|
|
429
|
+
}, paths[pathName])
|
|
430
430
|
const rf = reflect(bx, by, cx, cy)
|
|
431
431
|
bx = rf[0]
|
|
432
432
|
by = rf[1]
|
|
@@ -441,7 +441,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
441
441
|
cx = parseFloat(pts[i++])
|
|
442
442
|
cy = parseFloat(pts[i++])
|
|
443
443
|
ensurePath()
|
|
444
|
-
paths[pathName] =
|
|
444
|
+
paths[pathName] = path2.appendBezier({
|
|
445
445
|
segments,
|
|
446
446
|
controlPoints: [
|
|
447
447
|
svg2cag([x1, y1], svgUnitsPmm),
|
|
@@ -454,13 +454,13 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
454
454
|
by = rf[1]
|
|
455
455
|
}
|
|
456
456
|
break
|
|
457
|
-
case 'h': // relative
|
|
457
|
+
case 'h': // relative Horizontal line to
|
|
458
458
|
while (pts.length >= i + 1) {
|
|
459
459
|
cx = cx + parseFloat(pts[i++])
|
|
460
460
|
paths[pathName] = appendPoints([svg2cag([cx, cy], svgUnitsPmm)], paths[pathName])
|
|
461
461
|
}
|
|
462
462
|
break
|
|
463
|
-
case 'H': // absolute
|
|
463
|
+
case 'H': // absolute Horizontal line to
|
|
464
464
|
while (pts.length >= i + 1) {
|
|
465
465
|
cx = parseFloat(pts[i++])
|
|
466
466
|
paths[pathName] = appendPoints([svg2cag([cx, cy], svgUnitsPmm)], paths[pathName])
|
|
@@ -494,13 +494,13 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
494
494
|
break
|
|
495
495
|
case 'z': // close current line
|
|
496
496
|
case 'Z':
|
|
497
|
-
paths[pathName] =
|
|
497
|
+
paths[pathName] = path2.close(paths[pathName])
|
|
498
498
|
cx = sx
|
|
499
499
|
cy = sy // return to the starting point
|
|
500
500
|
pc = true
|
|
501
501
|
break
|
|
502
502
|
default:
|
|
503
|
-
console.log('Warning:
|
|
503
|
+
console.log('Warning: Unknown PATH command [' + co.c + ']')
|
|
504
504
|
break
|
|
505
505
|
}
|
|
506
506
|
|