@linkiez/dxf-renew 7.1.0 → 7.2.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/.eslintrc.json +1 -16
- package/.yarn/install-state.gz +0 -0
- package/ARCHITECTURE.md +163 -0
- package/CHANGELOG.md +16 -0
- package/README.md +72 -10
- package/{PLAN.md → ROADMAP.md} +227 -35
- package/dist/dxf.js +1090 -344
- package/docs/FIXTURE_VALIDATION_EZDXF.md +1 -1
- package/lib/Helper.cjs +4 -0
- package/lib/Helper.cjs.map +3 -3
- package/lib/Helper.js +4 -0
- package/lib/Helper.js.map +2 -2
- package/lib/entityToPolyline.cjs +95 -0
- package/lib/entityToPolyline.cjs.map +3 -3
- package/lib/entityToPolyline.js +95 -0
- package/lib/entityToPolyline.js.map +2 -2
- package/lib/handlers/entities.cjs +22 -2
- package/lib/handlers/entities.cjs.map +3 -3
- package/lib/handlers/entities.js +22 -2
- package/lib/handlers/entities.js.map +2 -2
- package/lib/handlers/entity/mleader.cjs +69 -0
- package/lib/handlers/entity/mleader.cjs.map +7 -0
- package/lib/handlers/entity/mleader.js +34 -0
- package/lib/handlers/entity/mleader.js.map +7 -0
- package/lib/handlers/entity/mline.cjs +91 -0
- package/lib/handlers/entity/mline.cjs.map +7 -0
- package/lib/handlers/entity/mline.js +56 -0
- package/lib/handlers/entity/mline.js.map +7 -0
- package/lib/handlers/entity/oleframe.cjs +98 -0
- package/lib/handlers/entity/oleframe.cjs.map +7 -0
- package/lib/handlers/entity/oleframe.js +63 -0
- package/lib/handlers/entity/oleframe.js.map +7 -0
- package/lib/handlers/entity/ray.cjs +81 -0
- package/lib/handlers/entity/ray.cjs.map +7 -0
- package/lib/handlers/entity/ray.js +46 -0
- package/lib/handlers/entity/ray.js.map +7 -0
- package/lib/handlers/entity/region.cjs +67 -0
- package/lib/handlers/entity/region.cjs.map +7 -0
- package/lib/handlers/entity/region.js +32 -0
- package/lib/handlers/entity/region.js.map +7 -0
- package/lib/handlers/entity/shape.cjs +95 -0
- package/lib/handlers/entity/shape.cjs.map +7 -0
- package/lib/handlers/entity/shape.js +60 -0
- package/lib/handlers/entity/shape.js.map +7 -0
- package/lib/handlers/entity/table.cjs +71 -0
- package/lib/handlers/entity/table.cjs.map +7 -0
- package/lib/handlers/entity/table.js +36 -0
- package/lib/handlers/entity/table.js.map +7 -0
- package/lib/handlers/entity/trace.cjs +101 -0
- package/lib/handlers/entity/trace.cjs.map +7 -0
- package/lib/handlers/entity/trace.js +66 -0
- package/lib/handlers/entity/trace.js.map +7 -0
- package/lib/handlers/entity/wipeout.cjs +122 -0
- package/lib/handlers/entity/wipeout.cjs.map +7 -0
- package/lib/handlers/entity/wipeout.js +87 -0
- package/lib/handlers/entity/wipeout.js.map +7 -0
- package/lib/handlers/entity/xline.cjs +81 -0
- package/lib/handlers/entity/xline.cjs.map +7 -0
- package/lib/handlers/entity/xline.js +46 -0
- package/lib/handlers/entity/xline.js.map +7 -0
- package/lib/handlers/objects.cjs +43 -1
- package/lib/handlers/objects.cjs.map +2 -2
- package/lib/handlers/objects.js +43 -1
- package/lib/handlers/objects.js.map +2 -2
- package/lib/handlers/tables.cjs +96 -17
- package/lib/handlers/tables.cjs.map +2 -2
- package/lib/handlers/tables.js +96 -17
- package/lib/handlers/tables.js.map +2 -2
- package/lib/index.cjs +5 -2
- package/lib/index.cjs.map +3 -3
- package/lib/index.js +18 -16
- package/lib/index.js.map +3 -3
- package/lib/toJson.cjs +29 -0
- package/lib/toJson.cjs.map +7 -0
- package/lib/toJson.js +9 -0
- package/lib/toJson.js.map +7 -0
- package/lib/toSVG.cjs +34 -3
- package/lib/toSVG.cjs.map +2 -2
- package/lib/toSVG.js +34 -3
- package/lib/toSVG.js.map +2 -2
- package/lib/types/entity.cjs.map +1 -1
- package/lib/types/helper.cjs.map +1 -1
- package/lib/types/index.cjs +20 -0
- package/lib/types/index.cjs.map +2 -2
- package/lib/types/index.js +10 -0
- package/lib/types/index.js.map +2 -2
- package/lib/types/mleader-entity.cjs +17 -0
- package/lib/types/mleader-entity.cjs.map +7 -0
- package/lib/types/mleader-entity.js +1 -0
- package/lib/types/mleader-entity.js.map +7 -0
- package/lib/types/mline-entity.cjs +17 -0
- package/lib/types/mline-entity.cjs.map +7 -0
- package/lib/types/mline-entity.js +1 -0
- package/lib/types/mline-entity.js.map +7 -0
- package/lib/types/oleframe-entity.cjs +17 -0
- package/lib/types/oleframe-entity.cjs.map +7 -0
- package/lib/types/oleframe-entity.js +1 -0
- package/lib/types/oleframe-entity.js.map +7 -0
- package/lib/types/options.cjs.map +1 -1
- package/lib/types/ray-entity.cjs +17 -0
- package/lib/types/ray-entity.cjs.map +7 -0
- package/lib/types/ray-entity.js +1 -0
- package/lib/types/ray-entity.js.map +7 -0
- package/lib/types/region-entity.cjs +17 -0
- package/lib/types/region-entity.cjs.map +7 -0
- package/lib/types/region-entity.js +1 -0
- package/lib/types/region-entity.js.map +7 -0
- package/lib/types/shape-entity.cjs +17 -0
- package/lib/types/shape-entity.cjs.map +7 -0
- package/lib/types/shape-entity.js +1 -0
- package/lib/types/shape-entity.js.map +7 -0
- package/lib/types/table-entity.cjs +17 -0
- package/lib/types/table-entity.cjs.map +7 -0
- package/lib/types/table-entity.js +1 -0
- package/lib/types/table-entity.js.map +7 -0
- package/lib/types/tables.cjs.map +1 -1
- package/lib/types/trace-entity.cjs +17 -0
- package/lib/types/trace-entity.cjs.map +7 -0
- package/lib/types/trace-entity.js +1 -0
- package/lib/types/trace-entity.js.map +7 -0
- package/lib/types/wipeout-entity.cjs +17 -0
- package/lib/types/wipeout-entity.cjs.map +7 -0
- package/lib/types/wipeout-entity.js +1 -0
- package/lib/types/wipeout-entity.js.map +7 -0
- package/lib/types/xline-entity.cjs +17 -0
- package/lib/types/xline-entity.cjs.map +7 -0
- package/lib/types/xline-entity.js +1 -0
- package/lib/types/xline-entity.js.map +7 -0
- package/package.json +5 -19
- package/src/Helper.ts +6 -1
- package/src/entityToPolyline.ts +124 -2
- package/src/handlers/entities.ts +21 -1
- package/src/handlers/entity/mleader.ts +46 -0
- package/src/handlers/entity/mline.ts +74 -0
- package/src/handlers/entity/oleframe.ts +62 -0
- package/src/handlers/entity/ray.ts +52 -0
- package/src/handlers/entity/region.ts +42 -0
- package/src/handlers/entity/shape.ts +73 -0
- package/src/handlers/entity/table.ts +49 -0
- package/src/handlers/entity/trace.ts +72 -0
- package/src/handlers/entity/wipeout.ts +114 -0
- package/src/handlers/entity/xline.ts +52 -0
- package/src/handlers/objects.ts +64 -8
- package/src/handlers/tables.ts +134 -21
- package/src/index.ts +9 -18
- package/src/toJson.ts +8 -0
- package/src/toSVG.ts +45 -3
- package/src/types/entity.ts +20 -0
- package/src/types/helper.ts +2 -1
- package/src/types/index.ts +10 -0
- package/src/types/mleader-entity.ts +8 -0
- package/src/types/mline-entity.ts +12 -0
- package/src/types/oleframe-entity.ts +40 -0
- package/src/types/options.ts +7 -0
- package/src/types/ray-entity.ts +12 -0
- package/src/types/region-entity.ts +11 -0
- package/src/types/shape-entity.ts +19 -0
- package/src/types/table-entity.ts +14 -0
- package/src/types/tables.ts +76 -0
- package/src/types/trace-entity.ts +14 -0
- package/src/types/wipeout-entity.ts +20 -0
- package/src/types/xline-entity.ts +12 -0
- package/docs/DIMENSION_SUMMARY.md +0 -254
- package/docs/DXF_VERSION_SUPPORT.md +0 -45
- package/docs/ENTITY_SVG_ROADMAP.md +0 -96
- package/docs/IMPLEMENTED-2D-ENTITIES.md +0 -54
- package/docs/README.md +0 -22
- package/docs/SVG_RENDERING_INTEGRATION_TESTS.md +0 -119
- package/docs/TEXT-MTEXT-DIMENSION-SUPPORT.md +0 -241
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { DXFTuple } from '../../types/dxf'
|
|
2
|
+
|
|
3
|
+
import type { Point3D } from '../../types'
|
|
4
|
+
import common from './common'
|
|
5
|
+
|
|
6
|
+
interface TraceEntity {
|
|
7
|
+
type: string
|
|
8
|
+
corners: Point3D[]
|
|
9
|
+
thickness?: number
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const TYPE = 'TRACE'
|
|
13
|
+
|
|
14
|
+
export const process = (tuples: DXFTuple[]): TraceEntity => {
|
|
15
|
+
return tuples.reduce(
|
|
16
|
+
(entity, tuple) => {
|
|
17
|
+
const type = tuple[0]
|
|
18
|
+
const value = tuple[1]
|
|
19
|
+
switch (type) {
|
|
20
|
+
case 10:
|
|
21
|
+
entity.corners[0].x = value as number
|
|
22
|
+
break
|
|
23
|
+
case 20:
|
|
24
|
+
entity.corners[0].y = value as number
|
|
25
|
+
break
|
|
26
|
+
case 30:
|
|
27
|
+
entity.corners[0].z = value as number
|
|
28
|
+
break
|
|
29
|
+
case 11:
|
|
30
|
+
entity.corners[1].x = value as number
|
|
31
|
+
break
|
|
32
|
+
case 21:
|
|
33
|
+
entity.corners[1].y = value as number
|
|
34
|
+
break
|
|
35
|
+
case 31:
|
|
36
|
+
entity.corners[1].z = value as number
|
|
37
|
+
break
|
|
38
|
+
case 12:
|
|
39
|
+
entity.corners[2].x = value as number
|
|
40
|
+
break
|
|
41
|
+
case 22:
|
|
42
|
+
entity.corners[2].y = value as number
|
|
43
|
+
break
|
|
44
|
+
case 32:
|
|
45
|
+
entity.corners[2].z = value as number
|
|
46
|
+
break
|
|
47
|
+
case 13:
|
|
48
|
+
entity.corners[3].x = value as number
|
|
49
|
+
break
|
|
50
|
+
case 23:
|
|
51
|
+
entity.corners[3].y = value as number
|
|
52
|
+
break
|
|
53
|
+
case 33:
|
|
54
|
+
entity.corners[3].z = value as number
|
|
55
|
+
break
|
|
56
|
+
case 39:
|
|
57
|
+
entity.thickness = value as number
|
|
58
|
+
break
|
|
59
|
+
default:
|
|
60
|
+
Object.assign(entity, common(type, value))
|
|
61
|
+
break
|
|
62
|
+
}
|
|
63
|
+
return entity
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
type: TYPE,
|
|
67
|
+
corners: [{} as Point3D, {} as Point3D, {} as Point3D, {} as Point3D],
|
|
68
|
+
} as TraceEntity,
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export default { TYPE, process }
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { DXFTuple, PartialPoint3D } from '../../types'
|
|
2
|
+
|
|
3
|
+
import common from './common'
|
|
4
|
+
|
|
5
|
+
export const TYPE = 'WIPEOUT'
|
|
6
|
+
|
|
7
|
+
interface WipeoutEntity {
|
|
8
|
+
type: typeof TYPE
|
|
9
|
+
|
|
10
|
+
insertionPoint: PartialPoint3D
|
|
11
|
+
uVector: PartialPoint3D
|
|
12
|
+
vVector: PartialPoint3D
|
|
13
|
+
|
|
14
|
+
clipBoundaryType?: 1 | 2
|
|
15
|
+
clipBoundaryVertices?: Array<{ x: number; y: number }>
|
|
16
|
+
|
|
17
|
+
displayProperties?: number
|
|
18
|
+
clippingState?: 0 | 1
|
|
19
|
+
classVersion?: number
|
|
20
|
+
imageSizePixels?: { u: number; v: number }
|
|
21
|
+
|
|
22
|
+
[key: string]: unknown
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const process = (tuples: DXFTuple[]): WipeoutEntity => {
|
|
26
|
+
let pendingBoundaryX: number | null = null
|
|
27
|
+
|
|
28
|
+
return tuples.reduce(
|
|
29
|
+
(entity, tuple) => {
|
|
30
|
+
const type = tuple[0]
|
|
31
|
+
const value = tuple[1]
|
|
32
|
+
|
|
33
|
+
switch (type) {
|
|
34
|
+
case 90:
|
|
35
|
+
entity.classVersion = value as number
|
|
36
|
+
break
|
|
37
|
+
|
|
38
|
+
case 10:
|
|
39
|
+
entity.insertionPoint.x = value as number
|
|
40
|
+
break
|
|
41
|
+
case 20:
|
|
42
|
+
entity.insertionPoint.y = value as number
|
|
43
|
+
break
|
|
44
|
+
case 30:
|
|
45
|
+
entity.insertionPoint.z = value as number
|
|
46
|
+
break
|
|
47
|
+
|
|
48
|
+
case 11:
|
|
49
|
+
entity.uVector.x = value as number
|
|
50
|
+
break
|
|
51
|
+
case 21:
|
|
52
|
+
entity.uVector.y = value as number
|
|
53
|
+
break
|
|
54
|
+
case 31:
|
|
55
|
+
entity.uVector.z = value as number
|
|
56
|
+
break
|
|
57
|
+
|
|
58
|
+
case 12:
|
|
59
|
+
entity.vVector.x = value as number
|
|
60
|
+
break
|
|
61
|
+
case 22:
|
|
62
|
+
entity.vVector.y = value as number
|
|
63
|
+
break
|
|
64
|
+
case 32:
|
|
65
|
+
entity.vVector.z = value as number
|
|
66
|
+
break
|
|
67
|
+
|
|
68
|
+
case 13:
|
|
69
|
+
entity.imageSizePixels ??= { u: 0, v: 0 }
|
|
70
|
+
entity.imageSizePixels.u = value as number
|
|
71
|
+
break
|
|
72
|
+
case 23:
|
|
73
|
+
entity.imageSizePixels ??= { u: 0, v: 0 }
|
|
74
|
+
entity.imageSizePixels.v = value as number
|
|
75
|
+
break
|
|
76
|
+
|
|
77
|
+
case 70:
|
|
78
|
+
entity.displayProperties = value as number
|
|
79
|
+
break
|
|
80
|
+
case 280:
|
|
81
|
+
entity.clippingState = value as 0 | 1
|
|
82
|
+
break
|
|
83
|
+
|
|
84
|
+
case 71:
|
|
85
|
+
entity.clipBoundaryType = value as 1 | 2
|
|
86
|
+
break
|
|
87
|
+
|
|
88
|
+
case 14:
|
|
89
|
+
pendingBoundaryX = value as number
|
|
90
|
+
break
|
|
91
|
+
case 24:
|
|
92
|
+
if (pendingBoundaryX !== null) {
|
|
93
|
+
entity.clipBoundaryVertices ??= []
|
|
94
|
+
entity.clipBoundaryVertices.push({ x: pendingBoundaryX, y: value as number })
|
|
95
|
+
pendingBoundaryX = null
|
|
96
|
+
}
|
|
97
|
+
break
|
|
98
|
+
|
|
99
|
+
default:
|
|
100
|
+
Object.assign(entity, common(type, value))
|
|
101
|
+
break
|
|
102
|
+
}
|
|
103
|
+
return entity
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
type: TYPE,
|
|
107
|
+
insertionPoint: {},
|
|
108
|
+
uVector: {},
|
|
109
|
+
vVector: {},
|
|
110
|
+
} as WipeoutEntity,
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export default { TYPE, process }
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { DXFTuple, PartialPoint3D } from '../../types'
|
|
2
|
+
|
|
3
|
+
import common from './common'
|
|
4
|
+
|
|
5
|
+
export const TYPE = 'XLINE'
|
|
6
|
+
|
|
7
|
+
interface XLineEntity {
|
|
8
|
+
type: typeof TYPE
|
|
9
|
+
basePoint: PartialPoint3D
|
|
10
|
+
direction: PartialPoint3D
|
|
11
|
+
[key: string]: unknown
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const process = (tuples: DXFTuple[]): XLineEntity => {
|
|
15
|
+
return tuples.reduce(
|
|
16
|
+
(entity, tuple) => {
|
|
17
|
+
const type = tuple[0]
|
|
18
|
+
const value = tuple[1]
|
|
19
|
+
switch (type) {
|
|
20
|
+
case 10:
|
|
21
|
+
entity.basePoint.x = value as number
|
|
22
|
+
break
|
|
23
|
+
case 20:
|
|
24
|
+
entity.basePoint.y = value as number
|
|
25
|
+
break
|
|
26
|
+
case 30:
|
|
27
|
+
entity.basePoint.z = value as number
|
|
28
|
+
break
|
|
29
|
+
case 11:
|
|
30
|
+
entity.direction.x = value as number
|
|
31
|
+
break
|
|
32
|
+
case 21:
|
|
33
|
+
entity.direction.y = value as number
|
|
34
|
+
break
|
|
35
|
+
case 31:
|
|
36
|
+
entity.direction.z = value as number
|
|
37
|
+
break
|
|
38
|
+
default:
|
|
39
|
+
Object.assign(entity, common(type, value))
|
|
40
|
+
break
|
|
41
|
+
}
|
|
42
|
+
return entity
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
type: TYPE,
|
|
46
|
+
basePoint: {},
|
|
47
|
+
direction: {},
|
|
48
|
+
} as XLineEntity,
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default { TYPE, process }
|
package/src/handlers/objects.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
DictionaryObject,
|
|
3
|
+
DimAssocObject,
|
|
4
|
+
DXFTuple,
|
|
5
|
+
FieldObject,
|
|
6
|
+
ImageDefObject,
|
|
7
|
+
ImageDefReactorObject,
|
|
8
|
+
LayoutInternal,
|
|
9
|
+
ParsedObjects,
|
|
10
|
+
UnderlayDefinitionObject,
|
|
11
|
+
XRecordObject,
|
|
10
12
|
} from '../types'
|
|
11
13
|
|
|
12
14
|
type ObjectGroup = DXFTuple[]
|
|
@@ -232,6 +234,48 @@ function parseImageDefReactorObject(group: ObjectGroup): ImageDefReactorObject |
|
|
|
232
234
|
return reactor
|
|
233
235
|
}
|
|
234
236
|
|
|
237
|
+
function parseDimAssocObject(group: ObjectGroup): DimAssocObject | undefined {
|
|
238
|
+
if (group[0]?.[1] !== 'DIMASSOC') return undefined
|
|
239
|
+
|
|
240
|
+
const tuples = group.slice(1)
|
|
241
|
+
|
|
242
|
+
const dimAssoc: DimAssocObject = {
|
|
243
|
+
type: 'DIMASSOC',
|
|
244
|
+
tuples,
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
for (const tuple of tuples) {
|
|
248
|
+
const type = tuple[0]
|
|
249
|
+
const value = tuple[1]
|
|
250
|
+
|
|
251
|
+
if (type === 5) dimAssoc.handle = value
|
|
252
|
+
if (type === 330) dimAssoc.ownerHandle = value
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return dimAssoc
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function parseFieldObject(group: ObjectGroup): FieldObject | undefined {
|
|
259
|
+
if (group[0]?.[1] !== 'FIELD') return undefined
|
|
260
|
+
|
|
261
|
+
const tuples = group.slice(1)
|
|
262
|
+
|
|
263
|
+
const field: FieldObject = {
|
|
264
|
+
type: 'FIELD',
|
|
265
|
+
tuples,
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
for (const tuple of tuples) {
|
|
269
|
+
const type = tuple[0]
|
|
270
|
+
const value = tuple[1]
|
|
271
|
+
|
|
272
|
+
if (type === 5) field.handle = value
|
|
273
|
+
if (type === 330) field.ownerHandle = value
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return field
|
|
277
|
+
}
|
|
278
|
+
|
|
235
279
|
const UNDERLAY_DEFINITION_OBJECT_TYPES = new Set([
|
|
236
280
|
'UNDERLAYDEFINITION',
|
|
237
281
|
'PDFDEFINITION',
|
|
@@ -311,6 +355,16 @@ const OBJECT_GROUP_HANDLERS: Record<string, ObjectGroupHandler> = {
|
|
|
311
355
|
const handle = def?.handle ? String(def.handle) : undefined
|
|
312
356
|
if (def && handle) objects.underlayDefinitions![handle] = def
|
|
313
357
|
},
|
|
358
|
+
DIMASSOC: (objects, group) => {
|
|
359
|
+
const dimAssoc = parseDimAssocObject(group)
|
|
360
|
+
const handle = dimAssoc?.handle ? String(dimAssoc.handle) : undefined
|
|
361
|
+
if (dimAssoc && handle) objects.dimAssocs![handle] = dimAssoc
|
|
362
|
+
},
|
|
363
|
+
FIELD: (objects, group) => {
|
|
364
|
+
const field = parseFieldObject(group)
|
|
365
|
+
const handle = field?.handle ? String(field.handle) : undefined
|
|
366
|
+
if (field && handle) objects.fields![handle] = field
|
|
367
|
+
},
|
|
314
368
|
}
|
|
315
369
|
|
|
316
370
|
export default function parseObjects(tuples: DXFTuple[]): ParsedObjects {
|
|
@@ -321,6 +375,8 @@ export default function parseObjects(tuples: DXFTuple[]): ParsedObjects {
|
|
|
321
375
|
imageDefs: {},
|
|
322
376
|
imageDefReactors: {},
|
|
323
377
|
underlayDefinitions: {},
|
|
378
|
+
dimAssocs: {},
|
|
379
|
+
fields: {},
|
|
324
380
|
}
|
|
325
381
|
|
|
326
382
|
const groups = groupObjectsByZero(tuples)
|
package/src/handlers/tables.ts
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
AppIdInternal,
|
|
3
|
+
BlockRecordInternal,
|
|
4
|
+
DXFTuple,
|
|
5
|
+
DimStyleInternal,
|
|
6
|
+
LTypeElement,
|
|
7
|
+
LTypeInternal,
|
|
8
|
+
LayerInternal,
|
|
9
|
+
StyleInternal,
|
|
10
|
+
UcsInternal,
|
|
11
|
+
VPortInternal,
|
|
12
|
+
ViewInternal,
|
|
13
|
+
} from '../types'
|
|
2
14
|
|
|
3
15
|
import logger from '../util/logger'
|
|
4
16
|
|
|
@@ -6,7 +18,7 @@ const ltypeHandler = (tuples: DXFTuple[]): LTypeInternal => {
|
|
|
6
18
|
let element: LTypeElement | undefined
|
|
7
19
|
let offset: { x: string | number; y: string | number } | undefined
|
|
8
20
|
return tuples.reduce(
|
|
9
|
-
(layer, tuple) => {
|
|
21
|
+
(layer, tuple) => { // NOSONAR
|
|
10
22
|
const type = tuple[0]
|
|
11
23
|
const value = tuple[1]
|
|
12
24
|
// https://documentation.help/AutoCAD-DXF/WS1a9193826455f5ff18cb41610ec0a2e719-7a4f.htm
|
|
@@ -172,7 +184,7 @@ const vPortHandler = (tuples: DXFTuple[]): VPortInternal => {
|
|
|
172
184
|
(vport, tuple) => {
|
|
173
185
|
const type = tuple[0]
|
|
174
186
|
const value = tuple[1]
|
|
175
|
-
switch (type) {
|
|
187
|
+
switch (type) { // NOSONAR
|
|
176
188
|
case 2:
|
|
177
189
|
vport.name = value
|
|
178
190
|
break
|
|
@@ -287,12 +299,100 @@ const vPortHandler = (tuples: DXFTuple[]): VPortInternal => {
|
|
|
287
299
|
)
|
|
288
300
|
}
|
|
289
301
|
|
|
302
|
+
const appIdHandler = (tuples: DXFTuple[]): AppIdInternal => {
|
|
303
|
+
return tuples.reduce(
|
|
304
|
+
(appId, tuple) => {
|
|
305
|
+
const type = tuple[0]
|
|
306
|
+
const value = tuple[1]
|
|
307
|
+
|
|
308
|
+
switch (type) {
|
|
309
|
+
case 2:
|
|
310
|
+
appId.name = value
|
|
311
|
+
break
|
|
312
|
+
case 70:
|
|
313
|
+
appId.flags = value
|
|
314
|
+
break
|
|
315
|
+
default:
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return appId
|
|
319
|
+
},
|
|
320
|
+
{ type: 'APPID' } as AppIdInternal,
|
|
321
|
+
)
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const blockRecordHandler = (tuples: DXFTuple[]): BlockRecordInternal => {
|
|
325
|
+
return tuples.reduce(
|
|
326
|
+
(blockRecord, tuple) => {
|
|
327
|
+
const type = tuple[0]
|
|
328
|
+
const value = tuple[1]
|
|
329
|
+
|
|
330
|
+
switch (type) {
|
|
331
|
+
case 2:
|
|
332
|
+
blockRecord.name = value
|
|
333
|
+
break
|
|
334
|
+
case 70:
|
|
335
|
+
blockRecord.flags = value
|
|
336
|
+
break
|
|
337
|
+
default:
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return blockRecord
|
|
341
|
+
},
|
|
342
|
+
{ type: 'BLOCK_RECORD' } as BlockRecordInternal,
|
|
343
|
+
)
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const ucsHandler = (tuples: DXFTuple[]): UcsInternal => {
|
|
347
|
+
return tuples.reduce(
|
|
348
|
+
(ucs, tuple) => {
|
|
349
|
+
const type = tuple[0]
|
|
350
|
+
const value = tuple[1]
|
|
351
|
+
|
|
352
|
+
switch (type) {
|
|
353
|
+
case 2:
|
|
354
|
+
ucs.name = value
|
|
355
|
+
break
|
|
356
|
+
case 70:
|
|
357
|
+
ucs.flags = value
|
|
358
|
+
break
|
|
359
|
+
default:
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return ucs
|
|
363
|
+
},
|
|
364
|
+
{ type: 'UCS' } as UcsInternal,
|
|
365
|
+
)
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
const viewHandler = (tuples: DXFTuple[]): ViewInternal => {
|
|
369
|
+
return tuples.reduce(
|
|
370
|
+
(view, tuple) => {
|
|
371
|
+
const type = tuple[0]
|
|
372
|
+
const value = tuple[1]
|
|
373
|
+
|
|
374
|
+
switch (type) {
|
|
375
|
+
case 2:
|
|
376
|
+
view.name = value
|
|
377
|
+
break
|
|
378
|
+
case 70:
|
|
379
|
+
view.flags = value
|
|
380
|
+
break
|
|
381
|
+
default:
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
return view
|
|
385
|
+
},
|
|
386
|
+
{ type: 'VIEW' } as ViewInternal,
|
|
387
|
+
)
|
|
388
|
+
}
|
|
389
|
+
|
|
290
390
|
const dimStyleHandler = (tuples: DXFTuple[]): DimStyleInternal => {
|
|
291
391
|
return tuples.reduce(
|
|
292
392
|
(dimStyle, tuple) => {
|
|
293
393
|
const type = tuple[0]
|
|
294
394
|
const value = tuple[1]
|
|
295
|
-
switch (type) {
|
|
395
|
+
switch (type) { // NOSONAR
|
|
296
396
|
case 2:
|
|
297
397
|
dimStyle.name = value
|
|
298
398
|
break
|
|
@@ -508,7 +608,18 @@ const dimStyleHandler = (tuples: DXFTuple[]): DimStyleInternal => {
|
|
|
508
608
|
const tableHandler = (
|
|
509
609
|
tuples: DXFTuple[],
|
|
510
610
|
tableType: string,
|
|
511
|
-
handler: (
|
|
611
|
+
handler: (
|
|
612
|
+
tuples: DXFTuple[],
|
|
613
|
+
) =>
|
|
614
|
+
| LTypeInternal
|
|
615
|
+
| LayerInternal
|
|
616
|
+
| StyleInternal
|
|
617
|
+
| VPortInternal
|
|
618
|
+
| DimStyleInternal
|
|
619
|
+
| AppIdInternal
|
|
620
|
+
| BlockRecordInternal
|
|
621
|
+
| UcsInternal
|
|
622
|
+
| ViewInternal,
|
|
512
623
|
): Record<string, any> => {
|
|
513
624
|
const tableRowsTuples: DXFTuple[][] = []
|
|
514
625
|
|
|
@@ -552,30 +663,32 @@ export default function parseTables(tuples: DXFTuple[]) {
|
|
|
552
663
|
}
|
|
553
664
|
}
|
|
554
665
|
|
|
555
|
-
|
|
556
|
-
let layersTuples: DXFTuple[] = []
|
|
557
|
-
let vPortTuples: DXFTuple[] = []
|
|
558
|
-
let ltypeTuples: DXFTuple[] = []
|
|
559
|
-
let dimStyleTuples: DXFTuple[] = []
|
|
666
|
+
const groupsByName: Record<string, DXFTuple[]> = {}
|
|
560
667
|
for (const group of tableGroups) {
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
ltypeTuples = group
|
|
565
|
-
} else if (group[0]?.[1] === 'LAYER') {
|
|
566
|
-
layersTuples = group
|
|
567
|
-
} else if (group[0]?.[1] === 'VPORT') {
|
|
568
|
-
vPortTuples = group
|
|
569
|
-
} else if (group[0]?.[1] === 'DIMSTYLE') {
|
|
570
|
-
dimStyleTuples = group
|
|
571
|
-
}
|
|
668
|
+
const name = String(group[0]?.[1] ?? '')
|
|
669
|
+
if (!name) continue
|
|
670
|
+
groupsByName[name] = group
|
|
572
671
|
}
|
|
573
672
|
|
|
673
|
+
const stylesTuples = groupsByName.STYLE ?? []
|
|
674
|
+
const layersTuples = groupsByName.LAYER ?? []
|
|
675
|
+
const vPortTuples = groupsByName.VPORT ?? []
|
|
676
|
+
const ltypeTuples = groupsByName.LTYPE ?? []
|
|
677
|
+
const dimStyleTuples = groupsByName.DIMSTYLE ?? []
|
|
678
|
+
const appIdTuples = groupsByName.APPID ?? []
|
|
679
|
+
const blockRecordTuples = groupsByName.BLOCK_RECORD ?? []
|
|
680
|
+
const ucsTuples = groupsByName.UCS ?? []
|
|
681
|
+
const viewTuples = groupsByName.VIEW ?? []
|
|
682
|
+
|
|
574
683
|
return {
|
|
575
684
|
layers: tableHandler(layersTuples, 'LAYER', layerHandler),
|
|
576
685
|
styles: tableHandler(stylesTuples, 'STYLE', styleHandler),
|
|
577
686
|
vports: tableHandler(vPortTuples, 'VPORT', vPortHandler),
|
|
578
687
|
ltypes: tableHandler(ltypeTuples, 'LTYPE', ltypeHandler),
|
|
579
688
|
dimStyles: tableHandler(dimStyleTuples, 'DIMSTYLE', dimStyleHandler),
|
|
689
|
+
appids: tableHandler(appIdTuples, 'APPID', appIdHandler),
|
|
690
|
+
blockRecords: tableHandler(blockRecordTuples, 'BLOCK_RECORD', blockRecordHandler),
|
|
691
|
+
ucs: tableHandler(ucsTuples, 'UCS', ucsHandler),
|
|
692
|
+
views: tableHandler(viewTuples, 'VIEW', viewHandler),
|
|
580
693
|
}
|
|
581
694
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,19 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
export { default as config } from './config'
|
|
2
|
+
export { default as denormalise } from './denormalise'
|
|
3
|
+
export { default as groupEntitiesByLayer } from './groupEntitiesByLayer'
|
|
4
|
+
export { default as Helper } from './Helper'
|
|
5
|
+
export { default as parseString } from './parseString'
|
|
6
|
+
export { default as toJson } from './toJson'
|
|
7
|
+
export { default as toPolylines } from './toPolylines'
|
|
8
|
+
export { default as toSVG } from './toSVG'
|
|
9
|
+
export { default as colors } from './util/colors'
|
|
9
10
|
|
|
10
|
-
export {
|
|
11
|
-
config,
|
|
12
|
-
parseString,
|
|
13
|
-
denormalise,
|
|
14
|
-
groupEntitiesByLayer,
|
|
15
|
-
toPolylines,
|
|
16
|
-
toSVG,
|
|
17
|
-
colors,
|
|
18
|
-
Helper,
|
|
19
|
-
}
|
package/src/toJson.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ParsedDXF, ToJsonOptions } from './types'
|
|
2
|
+
|
|
3
|
+
export default function toJson(parsed: ParsedDXF, options: ToJsonOptions = {}): string {
|
|
4
|
+
const shouldPrettyPrint = options.pretty === true
|
|
5
|
+
const indentation = shouldPrettyPrint ? (options.space ?? 2) : undefined
|
|
6
|
+
|
|
7
|
+
return JSON.stringify(parsed, null, indentation)
|
|
8
|
+
}
|
package/src/toSVG.ts
CHANGED
|
@@ -20,6 +20,7 @@ import type {
|
|
|
20
20
|
LeaderEntity,
|
|
21
21
|
MTextEntity,
|
|
22
22
|
ParsedDXF,
|
|
23
|
+
ShapeEntity,
|
|
23
24
|
SplineEntity,
|
|
24
25
|
TextEntity,
|
|
25
26
|
ToleranceEntity,
|
|
@@ -402,6 +403,32 @@ const tolerance = (entity: ToleranceEntity): BoundsAndElement => {
|
|
|
402
403
|
return transformBoundingBoxAndElement(bbox, element, entity.transforms ?? [])
|
|
403
404
|
}
|
|
404
405
|
|
|
406
|
+
/**
|
|
407
|
+
* Minimal <text /> fallback for SHAPE entities.
|
|
408
|
+
* Rendering SHX-based shapes is out of scope; we render the name as text.
|
|
409
|
+
*/
|
|
410
|
+
const shape = (entity: ShapeEntity): BoundsAndElement => {
|
|
411
|
+
const x = entity.insertionPoint?.x ?? 0
|
|
412
|
+
const y = entity.insertionPoint?.y ?? 0
|
|
413
|
+
const height = entity.size ?? 1
|
|
414
|
+
const rotation = entity.rotation ?? 0
|
|
415
|
+
const content = entity.name ?? ''
|
|
416
|
+
|
|
417
|
+
const textWidth = content.length * height * 0.6
|
|
418
|
+
const bbox0 = new Box2()
|
|
419
|
+
.expandByPoint({ x, y })
|
|
420
|
+
.expandByPoint({ x: x + textWidth, y: y + height })
|
|
421
|
+
|
|
422
|
+
const rotationDegrees = (rotation * 180) / Math.PI
|
|
423
|
+
const element0 = `<text x="${x}" y="${y}" font-size="${height}" transform="rotate(${-rotationDegrees} ${x} ${y}) scale(1,-1) translate(0 ${-2 * y})">${escapeXmlText(content)}</text>`
|
|
424
|
+
|
|
425
|
+
const { bbox, element } = addFlipXIfApplicable(entity, {
|
|
426
|
+
bbox: bbox0,
|
|
427
|
+
element: element0,
|
|
428
|
+
})
|
|
429
|
+
return transformBoundingBoxAndElement(bbox, element, entity.transforms ?? [])
|
|
430
|
+
}
|
|
431
|
+
|
|
405
432
|
/**
|
|
406
433
|
* Create dimension visualization with DIMSTYLE support
|
|
407
434
|
*/
|
|
@@ -504,18 +531,30 @@ const entityToBoundsAndElement = (
|
|
|
504
531
|
}
|
|
505
532
|
}
|
|
506
533
|
case 'LINE':
|
|
534
|
+
case 'RAY':
|
|
535
|
+
case 'XLINE':
|
|
507
536
|
case 'POLYLINE': {
|
|
508
537
|
return polyline(entity)
|
|
509
538
|
}
|
|
539
|
+
case 'SOLID':
|
|
540
|
+
case 'TRACE': {
|
|
541
|
+
return polyline(entity)
|
|
542
|
+
}
|
|
510
543
|
case 'LWPOLYLINE': {
|
|
511
544
|
return lwpolyline(entity)
|
|
512
545
|
}
|
|
546
|
+
case 'WIPEOUT': {
|
|
547
|
+
return polyline(entity)
|
|
548
|
+
}
|
|
513
549
|
case 'LEADER': {
|
|
514
550
|
return leader(entity as LeaderEntity)
|
|
515
551
|
}
|
|
516
552
|
case 'TOLERANCE': {
|
|
517
553
|
return tolerance(entity as ToleranceEntity)
|
|
518
554
|
}
|
|
555
|
+
case 'SHAPE': {
|
|
556
|
+
return shape(entity as ShapeEntity)
|
|
557
|
+
}
|
|
519
558
|
default:
|
|
520
559
|
logger.warn('entity type not supported in SVG rendering:', entity.type)
|
|
521
560
|
return null
|
|
@@ -569,9 +608,12 @@ export default function toSVG(parsed: ParsedDXF, options: ToSVGOptions = {}): st
|
|
|
569
608
|
acc.bbox.expandByPoint(bbox.min)
|
|
570
609
|
acc.bbox.expandByPoint(bbox.max)
|
|
571
610
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
611
|
+
const color = rgbToColorAttribute(rgb)
|
|
612
|
+
if (entity.type === 'SOLID' || entity.type === 'TRACE') {
|
|
613
|
+
acc.elements.push(`<g fill="${color}" stroke="none">${element}</g>`)
|
|
614
|
+
} else {
|
|
615
|
+
acc.elements.push(`<g stroke="${color}">${element}</g>`)
|
|
616
|
+
}
|
|
575
617
|
}
|
|
576
618
|
return acc
|
|
577
619
|
},
|