@linkiez/dxf-renew 7.0.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.
Files changed (252) hide show
  1. package/.eslintrc.json +1 -16
  2. package/.github/instructions/code-patterns.instructions.md +1 -1
  3. package/.github/instructions/exdxf.instruction.md +161 -0
  4. package/.github/instructions/tdd.instructions.md +271 -0
  5. package/.yarn/install-state.gz +0 -0
  6. package/ARCHITECTURE.md +163 -0
  7. package/CHANGELOG.md +39 -0
  8. package/CONTRIBUTING.md +16 -14
  9. package/README.md +113 -16
  10. package/{PLAN.md → ROADMAP.md} +244 -102
  11. package/dist/dxf.js +2212 -454
  12. package/docs/EZDXF_REFERENCE_SITEMAP.md +55 -0
  13. package/docs/FIXTURE_VALIDATION_EZDXF.md +62 -0
  14. package/lib/Helper.cjs +6 -2
  15. package/lib/Helper.cjs.map +3 -3
  16. package/lib/Helper.js +6 -2
  17. package/lib/Helper.js.map +2 -2
  18. package/lib/denormalise.cjs +131 -91
  19. package/lib/denormalise.cjs.map +2 -2
  20. package/lib/denormalise.js +131 -91
  21. package/lib/denormalise.js.map +2 -2
  22. package/lib/dimensionToSVG.cjs +318 -53
  23. package/lib/dimensionToSVG.cjs.map +3 -3
  24. package/lib/dimensionToSVG.js +316 -52
  25. package/lib/dimensionToSVG.js.map +2 -2
  26. package/lib/entityToPolyline.cjs +95 -0
  27. package/lib/entityToPolyline.cjs.map +3 -3
  28. package/lib/entityToPolyline.js +95 -0
  29. package/lib/entityToPolyline.js.map +2 -2
  30. package/lib/handlers/entities.cjs +111 -27
  31. package/lib/handlers/entities.cjs.map +3 -3
  32. package/lib/handlers/entities.js +111 -27
  33. package/lib/handlers/entities.js.map +3 -3
  34. package/lib/handlers/entity/dgnUnderlay.cjs +106 -0
  35. package/lib/handlers/entity/dgnUnderlay.cjs.map +7 -0
  36. package/lib/handlers/entity/dgnUnderlay.js +71 -0
  37. package/lib/handlers/entity/dgnUnderlay.js.map +7 -0
  38. package/lib/handlers/entity/dimension.cjs +24 -0
  39. package/lib/handlers/entity/dimension.cjs.map +2 -2
  40. package/lib/handlers/entity/dimension.js +24 -0
  41. package/lib/handlers/entity/dimension.js.map +2 -2
  42. package/lib/handlers/entity/dwfUnderlay.cjs +106 -0
  43. package/lib/handlers/entity/dwfUnderlay.cjs.map +7 -0
  44. package/lib/handlers/entity/dwfUnderlay.js +71 -0
  45. package/lib/handlers/entity/dwfUnderlay.js.map +7 -0
  46. package/lib/handlers/entity/image.cjs +123 -0
  47. package/lib/handlers/entity/image.cjs.map +7 -0
  48. package/lib/handlers/entity/image.js +88 -0
  49. package/lib/handlers/entity/image.js.map +7 -0
  50. package/lib/handlers/entity/leader.cjs +148 -0
  51. package/lib/handlers/entity/leader.cjs.map +7 -0
  52. package/lib/handlers/entity/leader.js +113 -0
  53. package/lib/handlers/entity/leader.js.map +7 -0
  54. package/lib/handlers/entity/mleader.cjs +69 -0
  55. package/lib/handlers/entity/mleader.cjs.map +7 -0
  56. package/lib/handlers/entity/mleader.js +34 -0
  57. package/lib/handlers/entity/mleader.js.map +7 -0
  58. package/lib/handlers/entity/mline.cjs +91 -0
  59. package/lib/handlers/entity/mline.cjs.map +7 -0
  60. package/lib/handlers/entity/mline.js +56 -0
  61. package/lib/handlers/entity/mline.js.map +7 -0
  62. package/lib/handlers/entity/oleframe.cjs +98 -0
  63. package/lib/handlers/entity/oleframe.cjs.map +7 -0
  64. package/lib/handlers/entity/oleframe.js +63 -0
  65. package/lib/handlers/entity/oleframe.js.map +7 -0
  66. package/lib/handlers/entity/pdfUnderlay.cjs +106 -0
  67. package/lib/handlers/entity/pdfUnderlay.cjs.map +7 -0
  68. package/lib/handlers/entity/pdfUnderlay.js +71 -0
  69. package/lib/handlers/entity/pdfUnderlay.js.map +7 -0
  70. package/lib/handlers/entity/ray.cjs +81 -0
  71. package/lib/handlers/entity/ray.cjs.map +7 -0
  72. package/lib/handlers/entity/ray.js +46 -0
  73. package/lib/handlers/entity/ray.js.map +7 -0
  74. package/lib/handlers/entity/region.cjs +67 -0
  75. package/lib/handlers/entity/region.cjs.map +7 -0
  76. package/lib/handlers/entity/region.js +32 -0
  77. package/lib/handlers/entity/region.js.map +7 -0
  78. package/lib/handlers/entity/shape.cjs +95 -0
  79. package/lib/handlers/entity/shape.cjs.map +7 -0
  80. package/lib/handlers/entity/shape.js +60 -0
  81. package/lib/handlers/entity/shape.js.map +7 -0
  82. package/lib/handlers/entity/table.cjs +71 -0
  83. package/lib/handlers/entity/table.cjs.map +7 -0
  84. package/lib/handlers/entity/table.js +36 -0
  85. package/lib/handlers/entity/table.js.map +7 -0
  86. package/lib/handlers/entity/tolerance.cjs +90 -0
  87. package/lib/handlers/entity/tolerance.cjs.map +7 -0
  88. package/lib/handlers/entity/tolerance.js +55 -0
  89. package/lib/handlers/entity/tolerance.js.map +7 -0
  90. package/lib/handlers/entity/trace.cjs +101 -0
  91. package/lib/handlers/entity/trace.cjs.map +7 -0
  92. package/lib/handlers/entity/trace.js +66 -0
  93. package/lib/handlers/entity/trace.js.map +7 -0
  94. package/lib/handlers/entity/wipeout.cjs +122 -0
  95. package/lib/handlers/entity/wipeout.cjs.map +7 -0
  96. package/lib/handlers/entity/wipeout.js +87 -0
  97. package/lib/handlers/entity/wipeout.js.map +7 -0
  98. package/lib/handlers/entity/xline.cjs +81 -0
  99. package/lib/handlers/entity/xline.cjs.map +7 -0
  100. package/lib/handlers/entity/xline.js +46 -0
  101. package/lib/handlers/entity/xline.js.map +7 -0
  102. package/lib/handlers/objects.cjs +299 -136
  103. package/lib/handlers/objects.cjs.map +2 -2
  104. package/lib/handlers/objects.js +299 -136
  105. package/lib/handlers/objects.js.map +2 -2
  106. package/lib/handlers/tables.cjs +96 -17
  107. package/lib/handlers/tables.cjs.map +2 -2
  108. package/lib/handlers/tables.js +96 -17
  109. package/lib/handlers/tables.js.map +2 -2
  110. package/lib/index.cjs +5 -2
  111. package/lib/index.cjs.map +3 -3
  112. package/lib/index.js +18 -16
  113. package/lib/index.js.map +3 -3
  114. package/lib/toJson.cjs +29 -0
  115. package/lib/toJson.cjs.map +7 -0
  116. package/lib/toJson.js +9 -0
  117. package/lib/toJson.js.map +7 -0
  118. package/lib/toSVG.cjs +105 -11
  119. package/lib/toSVG.cjs.map +3 -3
  120. package/lib/toSVG.js +106 -12
  121. package/lib/toSVG.js.map +2 -2
  122. package/lib/types/dimension-entity.cjs.map +1 -1
  123. package/lib/types/entity.cjs.map +1 -1
  124. package/lib/types/helper.cjs.map +1 -1
  125. package/lib/types/image-entity.cjs +17 -0
  126. package/lib/types/image-entity.cjs.map +7 -0
  127. package/lib/types/image-entity.js +1 -0
  128. package/lib/types/image-entity.js.map +7 -0
  129. package/lib/types/index.cjs +28 -0
  130. package/lib/types/index.cjs.map +2 -2
  131. package/lib/types/index.js +14 -0
  132. package/lib/types/index.js.map +2 -2
  133. package/lib/types/leader-entity.cjs +17 -0
  134. package/lib/types/leader-entity.cjs.map +7 -0
  135. package/lib/types/leader-entity.js +1 -0
  136. package/lib/types/leader-entity.js.map +7 -0
  137. package/lib/types/mleader-entity.cjs +17 -0
  138. package/lib/types/mleader-entity.cjs.map +7 -0
  139. package/lib/types/mleader-entity.js +1 -0
  140. package/lib/types/mleader-entity.js.map +7 -0
  141. package/lib/types/mline-entity.cjs +17 -0
  142. package/lib/types/mline-entity.cjs.map +7 -0
  143. package/lib/types/mline-entity.js +1 -0
  144. package/lib/types/mline-entity.js.map +7 -0
  145. package/lib/types/oleframe-entity.cjs +17 -0
  146. package/lib/types/oleframe-entity.cjs.map +7 -0
  147. package/lib/types/oleframe-entity.js +1 -0
  148. package/lib/types/oleframe-entity.js.map +7 -0
  149. package/lib/types/options.cjs.map +1 -1
  150. package/lib/types/ray-entity.cjs +17 -0
  151. package/lib/types/ray-entity.cjs.map +7 -0
  152. package/lib/types/ray-entity.js +1 -0
  153. package/lib/types/ray-entity.js.map +7 -0
  154. package/lib/types/region-entity.cjs +17 -0
  155. package/lib/types/region-entity.cjs.map +7 -0
  156. package/lib/types/region-entity.js +1 -0
  157. package/lib/types/region-entity.js.map +7 -0
  158. package/lib/types/shape-entity.cjs +17 -0
  159. package/lib/types/shape-entity.cjs.map +7 -0
  160. package/lib/types/shape-entity.js +1 -0
  161. package/lib/types/shape-entity.js.map +7 -0
  162. package/lib/types/table-entity.cjs +17 -0
  163. package/lib/types/table-entity.cjs.map +7 -0
  164. package/lib/types/table-entity.js +1 -0
  165. package/lib/types/table-entity.js.map +7 -0
  166. package/lib/types/tables.cjs.map +1 -1
  167. package/lib/types/tolerance-entity.cjs +17 -0
  168. package/lib/types/tolerance-entity.cjs.map +7 -0
  169. package/lib/types/tolerance-entity.js +1 -0
  170. package/lib/types/tolerance-entity.js.map +7 -0
  171. package/lib/types/trace-entity.cjs +17 -0
  172. package/lib/types/trace-entity.cjs.map +7 -0
  173. package/lib/types/trace-entity.js +1 -0
  174. package/lib/types/trace-entity.js.map +7 -0
  175. package/lib/types/underlay-entity.cjs +17 -0
  176. package/lib/types/underlay-entity.cjs.map +7 -0
  177. package/lib/types/underlay-entity.js +1 -0
  178. package/lib/types/underlay-entity.js.map +7 -0
  179. package/lib/types/wipeout-entity.cjs +17 -0
  180. package/lib/types/wipeout-entity.cjs.map +7 -0
  181. package/lib/types/wipeout-entity.js +1 -0
  182. package/lib/types/wipeout-entity.js.map +7 -0
  183. package/lib/types/xline-entity.cjs +17 -0
  184. package/lib/types/xline-entity.cjs.map +7 -0
  185. package/lib/types/xline-entity.js +1 -0
  186. package/lib/types/xline-entity.js.map +7 -0
  187. package/lib/util/escapeXmlText.cjs +27 -0
  188. package/lib/util/escapeXmlText.cjs.map +7 -0
  189. package/lib/util/escapeXmlText.js +7 -0
  190. package/lib/util/escapeXmlText.js.map +7 -0
  191. package/package.json +9 -18
  192. package/playwright.config.cjs +20 -0
  193. package/src/Helper.ts +8 -3
  194. package/src/denormalise.ts +182 -116
  195. package/src/dimensionToSVG.ts +466 -54
  196. package/src/entityToPolyline.ts +124 -2
  197. package/src/handlers/entities.ts +129 -34
  198. package/src/handlers/entity/dgnUnderlay.ts +94 -0
  199. package/src/handlers/entity/dimension.ts +27 -1
  200. package/src/handlers/entity/dwfUnderlay.ts +94 -0
  201. package/src/handlers/entity/image.ts +118 -0
  202. package/src/handlers/entity/leader.ts +153 -0
  203. package/src/handlers/entity/mleader.ts +46 -0
  204. package/src/handlers/entity/mline.ts +74 -0
  205. package/src/handlers/entity/oleframe.ts +62 -0
  206. package/src/handlers/entity/pdfUnderlay.ts +94 -0
  207. package/src/handlers/entity/ray.ts +52 -0
  208. package/src/handlers/entity/region.ts +42 -0
  209. package/src/handlers/entity/shape.ts +73 -0
  210. package/src/handlers/entity/table.ts +49 -0
  211. package/src/handlers/entity/tolerance.ts +75 -0
  212. package/src/handlers/entity/trace.ts +72 -0
  213. package/src/handlers/entity/wipeout.ts +114 -0
  214. package/src/handlers/entity/xline.ts +52 -0
  215. package/src/handlers/objects.ts +379 -139
  216. package/src/handlers/tables.ts +134 -21
  217. package/src/index.ts +9 -18
  218. package/src/toJson.ts +8 -0
  219. package/src/toSVG.ts +143 -10
  220. package/src/types/dimension-entity.ts +11 -0
  221. package/src/types/entity.ts +30 -0
  222. package/src/types/helper.ts +2 -1
  223. package/src/types/image-entity.ts +35 -0
  224. package/src/types/index.ts +14 -0
  225. package/src/types/leader-entity.ts +40 -0
  226. package/src/types/mleader-entity.ts +8 -0
  227. package/src/types/mline-entity.ts +12 -0
  228. package/src/types/oleframe-entity.ts +40 -0
  229. package/src/types/options.ts +48 -0
  230. package/src/types/ray-entity.ts +12 -0
  231. package/src/types/region-entity.ts +11 -0
  232. package/src/types/shape-entity.ts +19 -0
  233. package/src/types/table-entity.ts +14 -0
  234. package/src/types/tables.ts +160 -0
  235. package/src/types/tolerance-entity.ts +20 -0
  236. package/src/types/trace-entity.ts +14 -0
  237. package/src/types/underlay-entity.ts +35 -0
  238. package/src/types/wipeout-entity.ts +20 -0
  239. package/src/types/xline-entity.ts +12 -0
  240. package/src/util/escapeXmlText.ts +10 -0
  241. package/tools/browser_test_server.cjs +87 -0
  242. package/tools/ezdxf_generate_dimensions_all_types.py +246 -0
  243. package/tools/ezdxf_generate_dimensions_angular_3p.py +59 -0
  244. package/tools/ezdxf_generate_dimensions_large_scale.py +87 -0
  245. package/tools/ezdxf_regenerate_problem_fixtures.py +184 -0
  246. package/tools/ezdxf_validate_fixtures.py +165 -0
  247. package/docs/DIMENSION_SUMMARY.md +0 -248
  248. package/docs/DIMENSION_SUMMARY.pt-BR.md +0 -248
  249. package/docs/IMPLEMENTED-2D-ENTITIES.md +0 -54
  250. package/docs/IMPLEMENTED-2D-ENTITIES.pt-BR.md +0 -54
  251. package/docs/TEXT-MTEXT-DIMENSION-SUPPORT.md +0 -241
  252. package/docs/TEXT-MTEXT-DIMENSION-SUPPORT.pt-BR.md +0 -169
@@ -1,152 +1,392 @@
1
- import type { DXFTuple, LayoutInternal, ParsedObjects } from '../types'
1
+ import type {
2
+ DictionaryObject,
3
+ DimAssocObject,
4
+ DXFTuple,
5
+ FieldObject,
6
+ ImageDefObject,
7
+ ImageDefReactorObject,
8
+ LayoutInternal,
9
+ ParsedObjects,
10
+ UnderlayDefinitionObject,
11
+ XRecordObject,
12
+ } from '../types'
2
13
 
3
- export default function parseObjects(tuples: DXFTuple[]): ParsedObjects {
4
- let state: 'IDLE' | 'layout' | 'AcDbLayout' | undefined
5
- const objects: ParsedObjects = {
6
- layouts: [],
7
- }
8
- let layout: LayoutInternal | undefined
14
+ type ObjectGroup = DXFTuple[]
15
+
16
+ function groupObjectsByZero(tuples: DXFTuple[]): ObjectGroup[] {
17
+ const groups: ObjectGroup[] = []
18
+ let current: ObjectGroup | undefined
9
19
 
10
20
  for (const tuple of tuples) {
21
+ const code = tuple[0]
22
+ if (code === 0) {
23
+ if (current && current.length > 0) groups.push(current)
24
+ current = [tuple]
25
+ continue
26
+ }
27
+ if (!current) continue
28
+ current.push(tuple)
29
+ }
30
+
31
+ if (current && current.length > 0) groups.push(current)
32
+ return groups
33
+ }
34
+
35
+ const LAYOUT_FLOAT_FIELDS: Record<number, keyof LayoutInternal> = {
36
+ 10: 'minLimitX',
37
+ 20: 'minLimitY',
38
+ 11: 'maxLimitX',
39
+ 21: 'maxLimitY',
40
+ 12: 'x',
41
+ 22: 'y',
42
+ 32: 'z',
43
+ 14: 'minX',
44
+ 24: 'minY',
45
+ 34: 'minZ',
46
+ 15: 'maxX',
47
+ 25: 'maxY',
48
+ 35: 'maxZ',
49
+ 146: 'elevation',
50
+ 13: 'ucsX',
51
+ 23: 'ucsY',
52
+ 33: 'ucsZ',
53
+ 16: 'ucsXaxisX',
54
+ 26: 'ucsXaxisY',
55
+ 36: 'ucsXaxisZ',
56
+ 17: 'ucsYaxisX',
57
+ 27: 'ucsYaxisY',
58
+ 37: 'ucsYaxisZ',
59
+ }
60
+
61
+ const LAYOUT_DIRECT_FIELDS: Record<number, keyof LayoutInternal> = {
62
+ 1: 'name',
63
+ 5: 'handle',
64
+ 71: 'tabOrder',
65
+ 330: 'tableRecord',
66
+ 331: 'lastActiveViewport',
67
+ 333: 'shadePlot',
68
+ }
69
+
70
+ const LAYOUT_UCS_TYPE: Record<number, LayoutInternal['ucsType']> = {
71
+ 0: 'NOT ORTHOGRAPHIC',
72
+ 1: 'TOP',
73
+ 2: 'BOTTOM',
74
+ 3: 'FRONT',
75
+ 4: 'BACK',
76
+ 5: 'LEFT',
77
+ 6: 'RIGHT',
78
+ }
79
+
80
+ type LayoutParseState = {
81
+ state: 'IDLE' | 'layout' | 'AcDbLayout'
82
+ layout?: LayoutInternal
83
+ }
84
+
85
+ function consumeLayoutStartTuple(current: LayoutParseState, tuple: DXFTuple): LayoutParseState {
86
+ if (tuple[1] === 'LAYOUT') return { state: 'layout', layout: {} }
87
+ return { state: 'IDLE', layout: current.layout }
88
+ }
89
+
90
+ function consumeLayoutSubclassTuple(current: LayoutParseState, tuple: DXFTuple): LayoutParseState {
91
+ if (tuple[0] === 100 && tuple[1] === 'AcDbLayout') return { state: 'AcDbLayout', layout: current.layout }
92
+ return current
93
+ }
94
+
95
+ function applyLayoutFieldTuple(layout: LayoutInternal, tuple: DXFTuple): void {
96
+ const type = tuple[0]
97
+ const value = tuple[1]
98
+
99
+ const floatKey = LAYOUT_FLOAT_FIELDS[type]
100
+ if (floatKey) {
101
+ ;(layout as any)[floatKey] = Number.parseFloat(String(value))
102
+ return
103
+ }
104
+
105
+ const directKey = LAYOUT_DIRECT_FIELDS[type]
106
+ if (directKey) {
107
+ ;(layout as any)[directKey] = value
108
+ return
109
+ }
110
+
111
+ if (type === 70) {
112
+ layout.flag = value === 1 ? 'PSLTSCALE' : 'LIMCHECK'
113
+ return
114
+ }
115
+
116
+ if (type === 76) {
117
+ const ucsType = LAYOUT_UCS_TYPE[Number(value)]
118
+ if (ucsType) layout.ucsType = ucsType
119
+ }
120
+ }
121
+
122
+ function consumeLayoutTuple(current: LayoutParseState, tuple: DXFTuple): LayoutParseState {
123
+ if (tuple[0] === 0) return consumeLayoutStartTuple(current, tuple)
124
+
125
+ if (current.state === 'layout') return consumeLayoutSubclassTuple(current, tuple)
126
+
127
+ if (current.state === 'AcDbLayout' && current.layout) applyLayoutFieldTuple(current.layout, tuple)
128
+ return current
129
+ }
130
+
131
+ function parseLayoutObject(group: ObjectGroup): LayoutInternal | undefined {
132
+ let current: LayoutParseState = { state: 'IDLE' }
133
+ for (const tuple of group) current = consumeLayoutTuple(current, tuple)
134
+ return current.layout
135
+ }
136
+
137
+ function parseDictionaryObject(group: ObjectGroup): DictionaryObject | undefined {
138
+ if (group[0]?.[1] !== 'DICTIONARY') return undefined
139
+
140
+ const dict: DictionaryObject = {
141
+ type: 'DICTIONARY',
142
+ entries: {},
143
+ }
144
+
145
+ let pendingKey: string | undefined
146
+ for (const tuple of group.slice(1)) {
11
147
  const type = tuple[0]
12
148
  const value = tuple[1]
13
- if (type === 0) {
14
- state = 'IDLE'
149
+
150
+ if (type === 5) {
151
+ dict.handle = value
152
+ continue
15
153
  }
16
- if (value === 'LAYOUT') {
17
- state = 'layout'
18
- layout = {}
19
- objects.layouts.push(layout)
154
+ if (type === 330) {
155
+ dict.ownerHandle = value
156
+ continue
20
157
  }
21
- if (state === 'layout' && type !== 0) {
22
- // wait until AcDbLayout shows up
23
- switch (type) {
24
- case 100:
25
- if (value === 'AcDbLayout') state = 'AcDbLayout'
26
- break
27
- }
158
+ if (type === 3) {
159
+ pendingKey = String(value)
160
+ continue
28
161
  }
29
- if (state === 'AcDbLayout' && type !== 0 && layout) {
30
- // save layout attributes
31
- switch (type) {
32
- case 1:
33
- layout.name = value
34
- break
35
- case 5:
36
- layout.handle = value
37
- break
38
- case 10:
39
- layout.minLimitX = Number.parseFloat(String(value))
40
- break
41
- case 20:
42
- layout.minLimitY = Number.parseFloat(String(value))
43
- break
44
- case 11:
45
- layout.maxLimitX = Number.parseFloat(String(value))
46
- break
47
- case 21:
48
- layout.maxLimitY = Number.parseFloat(String(value))
49
- break
50
- case 12:
51
- layout.x = Number.parseFloat(String(value))
52
- break
53
- case 22:
54
- layout.y = Number.parseFloat(String(value))
55
- break
56
- case 32:
57
- layout.z = Number.parseFloat(String(value))
58
- break
59
- case 14:
60
- layout.minX = Number.parseFloat(String(value))
61
- break
62
- case 24:
63
- layout.minY = Number.parseFloat(String(value))
64
- break
65
- case 34:
66
- layout.minZ = Number.parseFloat(String(value))
67
- break
68
- case 15:
69
- layout.maxX = Number.parseFloat(String(value))
70
- break
71
- case 25:
72
- layout.maxY = Number.parseFloat(String(value))
73
- break
74
- case 35:
75
- layout.maxZ = Number.parseFloat(String(value))
76
- break
77
- case 70:
78
- layout.flag = value === 1 ? 'PSLTSCALE' : 'LIMCHECK'
79
- break
80
- case 71:
81
- layout.tabOrder = value
82
- break
83
- case 146:
84
- layout.elevation = Number.parseFloat(String(value))
85
- break
86
- case 13:
87
- layout.ucsX = Number.parseFloat(String(value))
88
- break
89
- case 23:
90
- layout.ucsY = Number.parseFloat(String(value))
91
- break
92
- case 33:
93
- layout.ucsZ = Number.parseFloat(String(value))
94
- break
95
- case 16:
96
- layout.ucsXaxisX = Number.parseFloat(String(value))
97
- break
98
- case 26:
99
- layout.ucsXaxisY = Number.parseFloat(String(value))
100
- break
101
- case 36:
102
- layout.ucsXaxisZ = Number.parseFloat(String(value))
103
- break
104
- case 17:
105
- layout.ucsYaxisX = Number.parseFloat(String(value))
106
- break
107
- case 27:
108
- layout.ucsYaxisY = Number.parseFloat(String(value))
109
- break
110
- case 37:
111
- layout.ucsYaxisZ = Number.parseFloat(String(value))
112
- break
113
- case 76:
114
- switch (value) {
115
- case 0:
116
- layout.ucsType = 'NOT ORTHOGRAPHIC'
117
- break
118
- case 1:
119
- layout.ucsType = 'TOP'
120
- break
121
- case 2:
122
- layout.ucsType = 'BOTTOM'
123
- break
124
- case 3:
125
- layout.ucsType = 'FRONT'
126
- break
127
- case 4:
128
- layout.ucsType = 'BACK'
129
- break
130
- case 5:
131
- layout.ucsType = 'LEFT'
132
- break
133
- case 6:
134
- layout.ucsType = 'RIGHT'
135
- break
136
- }
137
- break
138
- case 330:
139
- layout.tableRecord = value
140
- break
141
- case 331:
142
- layout.lastActiveViewport = value
143
- break
144
- case 333:
145
- layout.shadePlot = value
146
- break
147
- }
162
+ if ((type === 350 || type === 360) && pendingKey) {
163
+ dict.entries[pendingKey] = String(value)
164
+ pendingKey = undefined
148
165
  }
149
166
  }
150
167
 
168
+ return dict
169
+ }
170
+
171
+ function parseXRecordObject(group: ObjectGroup): XRecordObject | undefined {
172
+ if (group[0]?.[1] !== 'XRECORD') return undefined
173
+
174
+ const tuples = group.slice(1)
175
+
176
+ const xRecord: XRecordObject = {
177
+ type: 'XRECORD',
178
+ tuples,
179
+ }
180
+
181
+ for (const tuple of tuples) {
182
+ const type = tuple[0]
183
+ const value = tuple[1]
184
+
185
+ if (type === 5) xRecord.handle = value
186
+ if (type === 330) xRecord.ownerHandle = value
187
+ }
188
+
189
+ return xRecord
190
+ }
191
+
192
+ function parseImageDefObject(group: ObjectGroup): ImageDefObject | undefined {
193
+ if (group[0]?.[1] !== 'IMAGEDEF') return undefined
194
+
195
+ const tuples = group.slice(1)
196
+
197
+ const imageDef: ImageDefObject = {
198
+ type: 'IMAGEDEF',
199
+ tuples,
200
+ }
201
+
202
+ for (const tuple of tuples) {
203
+ const type = tuple[0]
204
+ const value = tuple[1]
205
+
206
+ if (type === 5) imageDef.handle = value
207
+ if (type === 330 && imageDef.ownerHandle === undefined) imageDef.ownerHandle = value
208
+ if (type === 1) imageDef.fileName = String(value)
209
+ if (type === 10) imageDef.pixelSizeX = Number(value)
210
+ if (type === 20) imageDef.pixelSizeY = Number(value)
211
+ }
212
+
213
+ return imageDef
214
+ }
215
+
216
+ function parseImageDefReactorObject(group: ObjectGroup): ImageDefReactorObject | undefined {
217
+ if (group[0]?.[1] !== 'IMAGEDEF_REACTOR') return undefined
218
+
219
+ const tuples = group.slice(1)
220
+
221
+ const reactor: ImageDefReactorObject = {
222
+ type: 'IMAGEDEF_REACTOR',
223
+ tuples,
224
+ }
225
+
226
+ for (const tuple of tuples) {
227
+ const type = tuple[0]
228
+ const value = tuple[1]
229
+
230
+ if (type === 5) reactor.handle = value
231
+ if (type === 330) reactor.imageHandle = value
232
+ }
233
+
234
+ return reactor
235
+ }
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
+
279
+ const UNDERLAY_DEFINITION_OBJECT_TYPES = new Set([
280
+ 'UNDERLAYDEFINITION',
281
+ 'PDFDEFINITION',
282
+ 'DWFDEFINITION',
283
+ 'DGNDEFINITION',
284
+ ])
285
+
286
+ function parseUnderlayDefinitionObject(group: ObjectGroup): UnderlayDefinitionObject | undefined {
287
+ const objectType = group[0]?.[1]
288
+ if (typeof objectType !== 'string') return undefined
289
+ if (!UNDERLAY_DEFINITION_OBJECT_TYPES.has(objectType)) return undefined
290
+
291
+ const tuples = group.slice(1)
292
+
293
+ const def: UnderlayDefinitionObject = {
294
+ type: objectType as UnderlayDefinitionObject['type'],
295
+ tuples,
296
+ }
297
+
298
+ for (const tuple of tuples) {
299
+ const type = tuple[0]
300
+ const value = tuple[1]
301
+
302
+ if (type === 5) def.handle = value
303
+ if (type === 330 && def.ownerHandle === undefined) def.ownerHandle = value
304
+ if (type === 1) def.fileName = String(value)
305
+ if (type === 2) def.underlayName = String(value)
306
+ }
307
+
308
+ return def
309
+ }
310
+
311
+ type ObjectGroupHandler = (objects: ParsedObjects, group: ObjectGroup) => void
312
+
313
+ const OBJECT_GROUP_HANDLERS: Record<string, ObjectGroupHandler> = {
314
+ LAYOUT: (objects, group) => {
315
+ const layout = parseLayoutObject(group)
316
+ if (layout) objects.layouts.push(layout)
317
+ },
318
+ DICTIONARY: (objects, group) => {
319
+ const dict = parseDictionaryObject(group)
320
+ const handle = dict?.handle ? String(dict.handle) : undefined
321
+ if (dict && handle) objects.dictionaries![handle] = dict
322
+ },
323
+ XRECORD: (objects, group) => {
324
+ const xRecord = parseXRecordObject(group)
325
+ const handle = xRecord?.handle ? String(xRecord.handle) : undefined
326
+ if (xRecord && handle) objects.xRecords![handle] = xRecord
327
+ },
328
+ IMAGEDEF: (objects, group) => {
329
+ const imageDef = parseImageDefObject(group)
330
+ const handle = imageDef?.handle ? String(imageDef.handle) : undefined
331
+ if (imageDef && handle) objects.imageDefs![handle] = imageDef
332
+ },
333
+ IMAGEDEF_REACTOR: (objects, group) => {
334
+ const reactor = parseImageDefReactorObject(group)
335
+ const handle = reactor?.handle ? String(reactor.handle) : undefined
336
+ if (reactor && handle) objects.imageDefReactors![handle] = reactor
337
+ },
338
+ UNDERLAYDEFINITION: (objects, group) => {
339
+ const def = parseUnderlayDefinitionObject(group)
340
+ const handle = def?.handle ? String(def.handle) : undefined
341
+ if (def && handle) objects.underlayDefinitions![handle] = def
342
+ },
343
+ PDFDEFINITION: (objects, group) => {
344
+ const def = parseUnderlayDefinitionObject(group)
345
+ const handle = def?.handle ? String(def.handle) : undefined
346
+ if (def && handle) objects.underlayDefinitions![handle] = def
347
+ },
348
+ DWFDEFINITION: (objects, group) => {
349
+ const def = parseUnderlayDefinitionObject(group)
350
+ const handle = def?.handle ? String(def.handle) : undefined
351
+ if (def && handle) objects.underlayDefinitions![handle] = def
352
+ },
353
+ DGNDEFINITION: (objects, group) => {
354
+ const def = parseUnderlayDefinitionObject(group)
355
+ const handle = def?.handle ? String(def.handle) : undefined
356
+ if (def && handle) objects.underlayDefinitions![handle] = def
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
+ },
368
+ }
369
+
370
+ export default function parseObjects(tuples: DXFTuple[]): ParsedObjects {
371
+ const objects: ParsedObjects = {
372
+ layouts: [],
373
+ dictionaries: {},
374
+ xRecords: {},
375
+ imageDefs: {},
376
+ imageDefReactors: {},
377
+ underlayDefinitions: {},
378
+ dimAssocs: {},
379
+ fields: {},
380
+ }
381
+
382
+ const groups = groupObjectsByZero(tuples)
383
+ for (const group of groups) {
384
+ const objectType = group[0]?.[1]
385
+ if (typeof objectType !== 'string') continue
386
+
387
+ const handler = OBJECT_GROUP_HANDLERS[objectType]
388
+ if (handler) handler(objects, group)
389
+ }
390
+
151
391
  return objects
152
392
  }