@jscad/svg-deserializer 2.5.6 → 3.0.0-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 +9 -206
- 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 +23 -12
- package/rollup.config.js +29 -0
- package/src/constants.js +6 -15
- package/src/helpers.js +11 -24
- package/src/index.js +23 -34
- package/src/shapesMapGeometry.js +36 -38
- package/src/shapesMapJscad.js +37 -39
- package/src/svgElementHelpers.js +16 -31
- package/tests/inkscape.test.js +5 -7
- package/tests/instantiate.test.js +102 -83
- package/tests/issue.1135.test.js +5 -5
- package/tests/issue.885.test.js +5 -9
- package/tests/translate.test.js +56 -60
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,26 +1,15 @@
|
|
|
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/)
|
|
9
|
-
|
|
10
|
-
All code released under MIT license
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
const saxes = require('saxes')
|
|
1
|
+
import saxes from 'saxes'
|
|
14
2
|
|
|
15
|
-
|
|
16
|
-
|
|
3
|
+
import { colorize, mirrorX, mirrorY, rotateZ, translate, scale } from '@jscad/modeling'
|
|
4
|
+
import { toArray } from '@jscad/array-utils'
|
|
17
5
|
|
|
18
|
-
|
|
6
|
+
import { pxPmm } from './constants.js'
|
|
7
|
+
import { cagLengthX, cagLengthY, svgColorForTarget } from './helpers.js'
|
|
8
|
+
import { svgSvg, svgRect, svgCircle, svgGroup, svgLine, svgPath, svgEllipse, svgPolygon, svgPolyline, svgUse } from './svgElementHelpers.js'
|
|
9
|
+
import { shapesMapGeometry } from './shapesMapGeometry.js'
|
|
10
|
+
import { shapesMapJscad } from './shapesMapJscad.js'
|
|
19
11
|
|
|
20
|
-
const {
|
|
21
|
-
const { svgSvg, svgRect, svgCircle, svgGroup, svgLine, svgPath, svgEllipse, svgPolygon, svgPolyline, svgUse } = require('./svgElementHelpers')
|
|
22
|
-
const shapesMapGeometry = require('./shapesMapGeometry')
|
|
23
|
-
const shapesMapJscad = require('./shapesMapJscad')
|
|
12
|
+
const version = '[VI]{version}[/VI]' // version is injected by rollup
|
|
24
13
|
|
|
25
14
|
/**
|
|
26
15
|
* Deserializer of SVG source data to JSCAD geometries.
|
|
@@ -51,14 +40,14 @@ const deserialize = (options, input) => {
|
|
|
51
40
|
addMetaData: true,
|
|
52
41
|
filename: 'svg',
|
|
53
42
|
output: 'script',
|
|
54
|
-
pxPmm
|
|
43
|
+
pxPmm,
|
|
55
44
|
segments: 32,
|
|
56
45
|
target: 'path', // target - 'geom2' or 'path'
|
|
57
46
|
pathSelfClosed: 'error',
|
|
58
47
|
version
|
|
59
48
|
}
|
|
60
49
|
options = Object.assign({}, defaults, options)
|
|
61
|
-
return options.output === 'script' ?
|
|
50
|
+
return options.output === 'script' ? translateScript(input, options) : instantiate(input, options)
|
|
62
51
|
}
|
|
63
52
|
|
|
64
53
|
/*
|
|
@@ -100,7 +89,7 @@ const instantiate = (src, options) => {
|
|
|
100
89
|
* at the start of the file
|
|
101
90
|
* @return {string} a string (JSCAD script)
|
|
102
91
|
*/
|
|
103
|
-
const
|
|
92
|
+
const translateScript = (src, options) => {
|
|
104
93
|
const { filename, version, pxPmm, addMetaData } = options
|
|
105
94
|
|
|
106
95
|
options && options.statusCallback && options.statusCallback({ progress: 0 })
|
|
@@ -192,29 +181,29 @@ const objectify = (options, group) => {
|
|
|
192
181
|
if (scaleAttribute !== null) {
|
|
193
182
|
let x = Math.abs(scaleAttribute.scale[0])
|
|
194
183
|
let y = Math.abs(scaleAttribute.scale[1])
|
|
195
|
-
shape =
|
|
184
|
+
shape = scale([x, y, 1], shape)
|
|
196
185
|
// and mirror if necessary
|
|
197
186
|
x = scaleAttribute.scale[0]
|
|
198
187
|
y = scaleAttribute.scale[1]
|
|
199
188
|
if (x < 0) {
|
|
200
|
-
shape =
|
|
189
|
+
shape = mirrorX(shape)
|
|
201
190
|
}
|
|
202
191
|
if (y < 0) {
|
|
203
|
-
shape =
|
|
192
|
+
shape = mirrorY(shape)
|
|
204
193
|
}
|
|
205
194
|
}
|
|
206
195
|
if (rotateAttribute !== null) {
|
|
207
196
|
const z = 0 - rotateAttribute.rotate * 0.017453292519943295 // radians
|
|
208
|
-
shape =
|
|
197
|
+
shape = rotateZ(z, shape)
|
|
209
198
|
}
|
|
210
199
|
if (translateAttribute !== null) {
|
|
211
200
|
const x = cagLengthX(translateAttribute.translate[0], svgUnitsPmm, svgUnitsX)
|
|
212
201
|
const y = (0 - cagLengthY(translateAttribute.translate[1], svgUnitsPmm, svgUnitsY))
|
|
213
|
-
shape =
|
|
202
|
+
shape = translate([x, y, 0], shape)
|
|
214
203
|
}
|
|
215
204
|
}
|
|
216
205
|
const color = svgColorForTarget(target, obj)
|
|
217
|
-
if (color) shape =
|
|
206
|
+
if (color) shape = colorize(color, shape)
|
|
218
207
|
return shape
|
|
219
208
|
})
|
|
220
209
|
geometries = geometries.concat(shapes)
|
|
@@ -364,7 +353,7 @@ const createSvgParser = (src, pxPmm) => {
|
|
|
364
353
|
// this is just like an embedded SVG but does NOT render directly, only named
|
|
365
354
|
// this requires another set of control objects
|
|
366
355
|
// only add to named objects for later USE
|
|
367
|
-
// break
|
|
356
|
+
// break
|
|
368
357
|
|
|
369
358
|
if (obj) {
|
|
370
359
|
// add to named objects if necessary
|
|
@@ -442,9 +431,9 @@ const createSvgParser = (src, pxPmm) => {
|
|
|
442
431
|
return parser
|
|
443
432
|
}
|
|
444
433
|
|
|
445
|
-
const
|
|
434
|
+
const mimeType = 'image/svg+xml'
|
|
446
435
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
436
|
+
export {
|
|
437
|
+
mimeType,
|
|
438
|
+
deserialize
|
|
450
439
|
}
|
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,8 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
188
185
|
pc = false
|
|
189
186
|
}
|
|
190
187
|
const ensurePath = () => {
|
|
191
|
-
if (!paths[pathName]) paths[pathName] =
|
|
188
|
+
if (!paths[pathName]) paths[pathName] =
|
|
189
|
+
path2.fromPoints({}, [])
|
|
192
190
|
}
|
|
193
191
|
for (let j = 0; j < obj.commands.length; j++) {
|
|
194
192
|
const co = obj.commands[j]
|
|
@@ -249,7 +247,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
249
247
|
cx = cx + parseFloat(pts[i++])
|
|
250
248
|
cy = cy + parseFloat(pts[i++])
|
|
251
249
|
ensurePath()
|
|
252
|
-
paths[pathName] =
|
|
250
|
+
paths[pathName] = path2.appendArc({
|
|
253
251
|
segments,
|
|
254
252
|
endpoint: svg2cag([cx, cy], svgUnitsPmm),
|
|
255
253
|
radius: svg2cag([rx, ry], svgUnitsPmm),
|
|
@@ -269,7 +267,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
269
267
|
cx = parseFloat(pts[i++])
|
|
270
268
|
cy = parseFloat(pts[i++])
|
|
271
269
|
ensurePath()
|
|
272
|
-
paths[pathName] =
|
|
270
|
+
paths[pathName] = path2.appendArc({
|
|
273
271
|
segments,
|
|
274
272
|
endpoint: svg2cag([cx, cy], svgUnitsPmm),
|
|
275
273
|
radius: svg2cag([rx, ry], svgUnitsPmm),
|
|
@@ -288,7 +286,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
288
286
|
cx = cx + parseFloat(pts[i++])
|
|
289
287
|
cy = cy + parseFloat(pts[i++])
|
|
290
288
|
ensurePath()
|
|
291
|
-
paths[pathName] =
|
|
289
|
+
paths[pathName] = path2.appendBezier({
|
|
292
290
|
segments,
|
|
293
291
|
controlPoints: [
|
|
294
292
|
svg2cag([x1, y1], svgUnitsPmm),
|
|
@@ -310,7 +308,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
310
308
|
cx = parseFloat(pts[i++])
|
|
311
309
|
cy = parseFloat(pts[i++])
|
|
312
310
|
ensurePath()
|
|
313
|
-
paths[pathName] =
|
|
311
|
+
paths[pathName] = path2.appendBezier({
|
|
314
312
|
segments,
|
|
315
313
|
controlPoints: [
|
|
316
314
|
svg2cag([x1, y1], svgUnitsPmm),
|
|
@@ -333,7 +331,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
333
331
|
const q1 = [p0[0] + (2/3) * (qx - p0[0]), p0[1] + (2/3) * (qy - p0[1])]
|
|
334
332
|
const q2 = [q1[0] + (1/3) * (cx - p0[0]), q1[1] + (1/3) * (cy - p0[1])]
|
|
335
333
|
ensurePath()
|
|
336
|
-
paths[pathName] =
|
|
334
|
+
paths[pathName] = path2.appendBezier({
|
|
337
335
|
segments,
|
|
338
336
|
controlPoints: [
|
|
339
337
|
svg2cag(q1, svgUnitsPmm),
|
|
@@ -356,7 +354,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
356
354
|
const q1 = [p0[0] + (2/3) * (qx - p0[0]), p0[1] + (2/3) * (qy - p0[1])]
|
|
357
355
|
const q2 = [q1[0] + (1/3) * (cx - p0[0]), q1[1] + (1/3) * (cy - p0[1])]
|
|
358
356
|
ensurePath()
|
|
359
|
-
paths[pathName] =
|
|
357
|
+
paths[pathName] = path2.appendBezier({
|
|
360
358
|
segments,
|
|
361
359
|
controlPoints: [
|
|
362
360
|
svg2cag(q1, svgUnitsPmm),
|
|
@@ -377,7 +375,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
377
375
|
const q1 = [p0[0] + (2/3) * (qx - p0[0]), p0[1] + (2/3) * (qy - p0[1])]
|
|
378
376
|
const q2 = [q1[0] + (1/3) * (cx - p0[0]), q1[1] + (1/3) * (cy - p0[1])]
|
|
379
377
|
ensurePath()
|
|
380
|
-
paths[pathName] =
|
|
378
|
+
paths[pathName] = path2.appendBezier({
|
|
381
379
|
segments,
|
|
382
380
|
controlPoints: [
|
|
383
381
|
svg2cag(q1, svgUnitsPmm),
|
|
@@ -398,7 +396,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
398
396
|
const q1 = [p0[0] + (2/3) * (qx - p0[0]), p0[1] + (2/3) * (qy - p0[1])]
|
|
399
397
|
const q2 = [q1[0] + (1/3) * (cx - p0[0]), q1[1] + (1/3) * (cy - p0[1])]
|
|
400
398
|
ensurePath()
|
|
401
|
-
paths[pathName] =
|
|
399
|
+
paths[pathName] = path2.appendBezier({
|
|
402
400
|
segments,
|
|
403
401
|
controlPoints: [
|
|
404
402
|
svg2cag(q1, svgUnitsPmm),
|
|
@@ -420,7 +418,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
420
418
|
cx = cx + parseFloat(pts[i++])
|
|
421
419
|
cy = cy + parseFloat(pts[i++])
|
|
422
420
|
ensurePath()
|
|
423
|
-
paths[pathName] =
|
|
421
|
+
paths[pathName] = path2.appendBezier({
|
|
424
422
|
segments, controlPoints: [
|
|
425
423
|
svg2cag([x1, y1], svgUnitsPmm),
|
|
426
424
|
svg2cag([bx, by], svgUnitsPmm),
|
|
@@ -441,7 +439,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
441
439
|
cx = parseFloat(pts[i++])
|
|
442
440
|
cy = parseFloat(pts[i++])
|
|
443
441
|
ensurePath()
|
|
444
|
-
paths[pathName] =
|
|
442
|
+
paths[pathName] = path2.appendBezier({
|
|
445
443
|
segments,
|
|
446
444
|
controlPoints: [
|
|
447
445
|
svg2cag([x1, y1], svgUnitsPmm),
|
|
@@ -454,13 +452,13 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
454
452
|
by = rf[1]
|
|
455
453
|
}
|
|
456
454
|
break
|
|
457
|
-
case 'h': // relative
|
|
455
|
+
case 'h': // relative Horizontal line to
|
|
458
456
|
while (pts.length >= i + 1) {
|
|
459
457
|
cx = cx + parseFloat(pts[i++])
|
|
460
458
|
paths[pathName] = appendPoints([svg2cag([cx, cy], svgUnitsPmm)], paths[pathName])
|
|
461
459
|
}
|
|
462
460
|
break
|
|
463
|
-
case 'H': // absolute
|
|
461
|
+
case 'H': // absolute Horizontal line to
|
|
464
462
|
while (pts.length >= i + 1) {
|
|
465
463
|
cx = parseFloat(pts[i++])
|
|
466
464
|
paths[pathName] = appendPoints([svg2cag([cx, cy], svgUnitsPmm)], paths[pathName])
|
|
@@ -494,13 +492,13 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
494
492
|
break
|
|
495
493
|
case 'z': // close current line
|
|
496
494
|
case 'Z':
|
|
497
|
-
paths[pathName] =
|
|
495
|
+
paths[pathName] = path2.close(paths[pathName])
|
|
498
496
|
cx = sx
|
|
499
497
|
cy = sy // return to the starting point
|
|
500
498
|
pc = true
|
|
501
499
|
break
|
|
502
500
|
default:
|
|
503
|
-
console.log('Warning:
|
|
501
|
+
console.log('Warning: Unknown PATH command [' + co.c + ']')
|
|
504
502
|
break
|
|
505
503
|
}
|
|
506
504
|
|
|
@@ -509,7 +507,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
509
507
|
if (pc !== true && paths[pathName] && paths[pathName].isClosed) {
|
|
510
508
|
let coNext = obj.commands[j + 1]
|
|
511
509
|
// allow self close in the last command #1135 (coNext is null or undefined)
|
|
512
|
-
// if do have a next command use pathSelfClosed to decide how to react to closing in the middle of a path
|
|
510
|
+
// if do have a next command use pathSelfClosed to decide how to react to closing in the middle of a path
|
|
513
511
|
if (coNext && !isCloseCmd(coNext.c)) {
|
|
514
512
|
if (pathSelfClosed === 'trim') {
|
|
515
513
|
while (coNext && !isCloseCmd(coNext.c)) {
|
|
@@ -518,7 +516,7 @@ const expandPath = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups
|
|
|
518
516
|
}
|
|
519
517
|
} else if (pathSelfClosed === 'split') {
|
|
520
518
|
newPath()
|
|
521
|
-
}else{
|
|
519
|
+
} else {
|
|
522
520
|
throw new Error(`Malformed svg path at ${obj.position[0]}:${co.pos}. Path closed itself with command #${j} ${co.c}${pts.join(' ')}`)
|
|
523
521
|
}
|
|
524
522
|
}
|