@design-core/core 0.0.6 → 50.1.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 (173) hide show
  1. package/.eslintrc.json +4 -0
  2. package/.github/workflows/DesignCoreQA.yml +3 -0
  3. package/TODO.md +49 -6
  4. package/core/core/core.js +0 -3
  5. package/core/designCore.js +1 -1
  6. package/core/dimensions/alignedDimension.js +12 -11
  7. package/core/dimensions/angularDimension.js +38 -37
  8. package/core/dimensions/{baseCircularDimension.js → circularDimensionBase.js} +22 -21
  9. package/core/dimensions/diametricDimension.js +14 -13
  10. package/core/dimensions/dimension.js +62 -55
  11. package/core/dimensions/{baseDimension.js → dimensionBase.js} +73 -107
  12. package/core/dimensions/{baseLinearDimension.js → linearDimensionBase.js} +15 -14
  13. package/core/dimensions/radialDimension.js +12 -11
  14. package/core/dimensions/rotatedDimension.js +20 -19
  15. package/core/entities/arc.js +123 -156
  16. package/core/entities/arctext.js +222 -184
  17. package/core/entities/circle.js +77 -99
  18. package/core/entities/entity.js +114 -93
  19. package/core/entities/hatch.js +346 -273
  20. package/core/entities/insert.js +68 -83
  21. package/core/entities/line.js +21 -142
  22. package/core/entities/lwpolyline.js +16 -11
  23. package/core/entities/point.js +19 -19
  24. package/core/entities/polyline.js +7 -7
  25. package/core/entities/{basePolyline.js → polylineBase.js} +47 -299
  26. package/core/entities/rectangle.js +3 -1
  27. package/core/entities/solid.js +6 -15
  28. package/core/entities/text.js +190 -201
  29. package/core/lib/auxiliary/rubberBand.js +32 -0
  30. package/core/lib/auxiliary/selectionWindow.js +63 -0
  31. package/core/lib/auxiliary/snapPoint.js +113 -0
  32. package/core/lib/auxiliary/trackingLine.js +76 -0
  33. package/core/lib/boundingBox.js +11 -11
  34. package/core/lib/canvas.js +232 -168
  35. package/core/lib/clipboard.js +9 -3
  36. package/core/lib/colour.js +16 -0
  37. package/core/lib/commandLine.js +1 -6
  38. package/core/lib/commandManager.js +18 -8
  39. package/core/lib/constants.js +28 -0
  40. package/core/lib/dxf/dxf.js +15 -14
  41. package/core/lib/dxf/dxfIterator.js +2 -2
  42. package/core/lib/entityManager.js +33 -26
  43. package/core/lib/inputManager.js +36 -12
  44. package/core/lib/intersect.js +25 -0
  45. package/core/lib/matrix.js +1 -1
  46. package/core/lib/patterns.js +9 -2
  47. package/core/lib/plotOptions.js +67 -0
  48. package/core/lib/polylineUtils.js +75 -0
  49. package/core/lib/renderers/cairoRenderer.js +371 -0
  50. package/core/lib/renderers/canvasRenderer.js +315 -0
  51. package/core/lib/renderers/pdfRenderer.js +366 -0
  52. package/core/lib/renderers/rendererBase.js +284 -0
  53. package/core/lib/renderers/svgRenderer.js +343 -0
  54. package/core/lib/scene.js +28 -6
  55. package/core/lib/selectionManager.js +20 -20
  56. package/core/lib/settings.js +4 -2
  57. package/core/lib/snapping.js +4 -191
  58. package/core/lib/stateManager.js +30 -1
  59. package/core/lib/utils.js +26 -7
  60. package/core/properties/entityProperties.js +104 -0
  61. package/core/properties/property.js +106 -2
  62. package/core/properties/propertyManager.js +60 -44
  63. package/core/tables/block.js +50 -81
  64. package/core/tables/dimStyle.js +5 -5
  65. package/core/tables/endblk.js +1 -1
  66. package/core/tables/layer.js +8 -0
  67. package/core/tables/ltypeManager.js +1 -1
  68. package/core/tables/styleManagerBase.js +3 -2
  69. package/core/tables/tableManagerBase.js +8 -3
  70. package/core/tables/vport.js +2 -2
  71. package/core/tools/chamfer.js +117 -143
  72. package/core/tools/chamferFilletBase.js +138 -37
  73. package/core/tools/copy.js +11 -11
  74. package/core/tools/copybase.js +3 -3
  75. package/core/tools/copyclip.js +3 -3
  76. package/core/tools/cornerEntity.js +2 -2
  77. package/core/tools/cutclip.js +3 -3
  78. package/core/tools/explode.js +7 -7
  79. package/core/tools/extend.js +138 -25
  80. package/core/tools/fillet.js +92 -189
  81. package/core/tools/matchProp.js +3 -12
  82. package/core/tools/mirror.js +15 -14
  83. package/core/tools/move.js +8 -8
  84. package/core/tools/offset.js +31 -33
  85. package/core/tools/pasteclip.js +1 -1
  86. package/core/tools/purge.js +10 -10
  87. package/core/tools/rotate.js +19 -16
  88. package/core/tools/scale.js +7 -7
  89. package/core/tools/trim.js +271 -29
  90. package/core/tools/zoom.js +1 -1
  91. package/cspell.json +321 -0
  92. package/jest.config.js +6 -0
  93. package/package.json +5 -3
  94. package/test/dimensions/alignedDimension.test.js +17 -10
  95. package/test/dimensions/angularDimension.test.js +13 -13
  96. package/test/dimensions/diametricDimension.test.js +15 -15
  97. package/test/dimensions/dimension.test.js +12 -12
  98. package/test/dimensions/{baseDimension.test.js → dimensionBase.test.js} +73 -12
  99. package/test/dimensions/linearDimensionBase.test.js +62 -0
  100. package/test/dimensions/radialDimension.test.js +15 -15
  101. package/test/dimensions/rotatedDimension.test.js +18 -11
  102. package/test/entities/arc.test.js +83 -86
  103. package/test/entities/arctext.test.js +184 -57
  104. package/test/entities/circle.test.js +68 -96
  105. package/test/entities/entity.test.js +42 -8
  106. package/test/entities/hatch.test.js +569 -96
  107. package/test/entities/insert.test.js +99 -4
  108. package/test/entities/line.test.js +15 -41
  109. package/test/entities/lwpolyline.test.js +104 -0
  110. package/test/entities/point.test.js +3 -3
  111. package/test/entities/polyline.test.js +11 -0
  112. package/test/entities/{basePolyline.test.js → polylineBase.test.js} +192 -57
  113. package/test/entities/rectangle.test.js +11 -0
  114. package/test/entities/solid.test.js +1 -1
  115. package/test/entities/text.test.js +302 -77
  116. package/test/integration/exportIntegration.reference.dxf +9 -9
  117. package/test/integration/exportIntegration.test.js +5 -5
  118. package/test/integration/intersectionIntegration.test.js +4 -5
  119. package/test/integration/pdfRendererIntegration.reference.pdf +17709 -0
  120. package/test/integration/pdfRendererIntegration.test.js +61 -0
  121. package/test/integration/svgRendererIntegration.reference.svg +3343 -0
  122. package/test/integration/svgRendererIntegration.test.js +61 -0
  123. package/test/integration/userInputIntegration.reference.dxf +1165 -105
  124. package/test/integration/userInputIntegration.test.js +239 -132
  125. package/test/lib/boundingBox.test.js +3 -3
  126. package/test/lib/canvas.test.js +744 -125
  127. package/test/lib/constants.test.js +27 -0
  128. package/test/lib/entityManager.test.js +4 -4
  129. package/test/lib/inputManager.test.js +81 -20
  130. package/test/lib/intersect.test.js +83 -0
  131. package/test/lib/plotOptions.test.js +179 -0
  132. package/test/lib/rubberBand.test.js +84 -0
  133. package/test/lib/scene.test.js +9 -9
  134. package/test/lib/selectionManager.test.js +3 -3
  135. package/test/lib/settings.test.js +5 -6
  136. package/test/lib/snapping.test.js +72 -130
  137. package/test/lib/stateManager.test.js +7 -7
  138. package/test/lib/utils.test.js +36 -2
  139. package/test/properties/entityProperties.test.js +132 -0
  140. package/test/properties/property.test.js +53 -0
  141. package/test/properties/propertyManager.test.js +25 -25
  142. package/test/renderers/canvasRenderer.test.js +317 -0
  143. package/test/renderers/pdfRenderer.test.js +271 -0
  144. package/test/renderers/rendererBase.test.js +213 -0
  145. package/test/renderers/svgRenderer.test.js +326 -0
  146. package/test/tables/block.test.js +92 -13
  147. package/test/tables/endblk.test.js +2 -2
  148. package/test/tables/layer.test.js +30 -0
  149. package/test/tables/layerManager.test.js +2 -2
  150. package/test/test-helpers/hatchGridRenderer.js +180 -0
  151. package/test/test-helpers/test-helpers.js +158 -6
  152. package/test/tools/chamfer.test.js +273 -51
  153. package/test/tools/chamferFilletBase.test.js +125 -36
  154. package/test/tools/copy.test.js +8 -8
  155. package/test/tools/copybase.test.js +2 -2
  156. package/test/tools/copyclip.test.js +2 -2
  157. package/test/tools/cornerEntity.test.js +8 -8
  158. package/test/tools/cutclip.test.js +2 -2
  159. package/test/tools/erase.test.js +6 -6
  160. package/test/tools/explode.test.js +5 -5
  161. package/test/tools/extend.test.js +373 -42
  162. package/test/tools/fillet.test.js +230 -49
  163. package/test/tools/matchProp.test.js +11 -11
  164. package/test/tools/mirror.test.js +39 -39
  165. package/test/tools/move.test.js +7 -7
  166. package/test/tools/offset.test.js +222 -55
  167. package/test/tools/pasteclip.test.js +5 -5
  168. package/test/tools/purge.test.js +4 -4
  169. package/test/tools/rotate.test.js +39 -9
  170. package/test/tools/scale.test.js +33 -33
  171. package/test/tools/trim.test.js +579 -53
  172. package/test/tools/zoom.test.js +12 -12
  173. package/core/lib/selectionWindow.js +0 -83
@@ -28,79 +28,81 @@ export class PropertyManager {
28
28
  }
29
29
 
30
30
  /**
31
- * Set item properties
31
+ * Set entity properties
32
32
  * @param {string} property
33
33
  * @param {any} newPropertyValue
34
- * @param {string} itemType
34
+ * @param {string} entityType
35
35
  */
36
- setItemProperties(property, newPropertyValue, itemType='All') {
36
+ setEntityProperties(property, newPropertyValue, entityType='All') {
37
37
  const stateChanges = [];
38
38
  for (let i = 0; i < DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
39
39
  const index = DesignCore.Scene.selectionManager.selectionSet.selectionSet[i];
40
40
 
41
- const item = DesignCore.Scene.entities.get(index);
41
+ const entity = DesignCore.Scene.entities.get(index);
42
42
 
43
- // check if the item is of the selected type
44
- if (itemType !== 'All' && item.type !== itemType) {
43
+ // check if the entity is of the selected type
44
+ if (entityType !== 'All' && entity.type !== entityType) {
45
45
  continue;
46
46
  }
47
47
 
48
- // check if the item has the selected property
49
- if (!item.hasOwnProperty(property)) {
48
+ // check if the entity has the selected property
49
+ if (!entity.properties?.has(property)) {
50
50
  continue;
51
51
  }
52
52
 
53
- if (typeof (item[property]) !== typeof (newPropertyValue)) {
53
+ const currentValue = entity.getProperty(property);
54
+
55
+ if (typeof (currentValue) !== typeof (newPropertyValue)) {
54
56
  DesignCore.Core.notify(Strings.Error.INPUT);
55
57
  } else {
56
- // update the item property
58
+ // update the entity property
57
59
  const update = {};
58
60
  update[property] = newPropertyValue;
59
- const stateChange = new UpdateState(item, update);
61
+ const stateChange = new UpdateState(entity, update);
60
62
  stateChanges.push(stateChange);
61
63
  }
62
64
  }
63
65
  DesignCore.Scene.commit(stateChanges);
64
- DesignCore.Scene.selectionManager.reloadSelectedItems();
66
+ DesignCore.Scene.selectionManager.reloadSelectedEntities();
65
67
  }
66
68
 
67
69
  /**
68
70
  * Get the types of items selected
69
71
  * @return {Array}
70
72
  */
71
- getItemTypes() {
72
- // Loop through the items and get a list of item types.
73
- const itemTypes = [];
73
+ getEntityTypes() {
74
+ // Loop through the items and get a list of entity types.
75
+ const entityTypes = [];
74
76
 
75
77
  if (DesignCore.Scene.selectionManager.selectionSet.selectionSet.length > 0) {
76
78
  for (let i = 0; i < DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
77
- const item = DesignCore.Scene.entities.get(DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]);
78
- const itemType = item.type;
79
+ const entity = DesignCore.Scene.entities.get(DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]);
80
+ const entityType = entity.type;
79
81
 
80
- if (itemTypes.indexOf(itemType, 0) === -1) {
81
- itemTypes.push(itemType);
82
+ if (entityTypes.indexOf(entityType, 0) === -1) {
83
+ entityTypes.push(entityType);
82
84
  }
83
85
  }
84
86
 
85
87
  // if there is more that one type add an option for all
86
- if (itemTypes.length > 1) {
87
- itemTypes.unshift('All');
88
+ if (entityTypes.length > 1) {
89
+ entityTypes.unshift('All');
88
90
  }
89
91
  }
90
92
 
91
- return itemTypes;
93
+ return entityTypes;
92
94
  }
93
95
 
94
96
  /**
95
- * Get a list of common propertie
96
- * @param {string} itemType
97
+ * Get a list of common properties
98
+ * @param {string} entityType
97
99
  * @return {Array}
98
100
  */
99
- getItemProperties(itemType) {
101
+ getEntityProperties(entityType) {
100
102
  // Loop through the items and get a list of common properties.
101
103
 
102
- // check for valid itemType and selectionSet
103
- if (itemType === undefined || itemType === null || DesignCore.Scene.selectionManager.selectionSet.selectionSet.length <= 0) {
104
+ // check for valid entityType and selectionSet
105
+ if (entityType === undefined || entityType === null || DesignCore.Scene.selectionManager.selectionSet.selectionSet.length <= 0) {
104
106
  return;
105
107
  }
106
108
 
@@ -112,48 +114,62 @@ export class PropertyManager {
112
114
  });
113
115
 
114
116
  // get a subset of the selectionSet
115
- if (itemType !== 'All') {
116
- subset = subset.filter((el) => el.type === itemType);
117
+ if (entityType !== 'All') {
118
+ subset = subset.filter((el) => el.type === entityType);
117
119
  }
118
120
 
119
121
  const propertiesList = [];
120
122
 
121
123
  subset.forEach((el) => {
122
- // get list of keys
123
- Object.keys(el).forEach((key) => {
124
- // check if the key is already in the propertiesList
125
- if (propertiesList.includes(key) === false) {
126
- // check if all subset items contain the key and the key is enumberable
127
- if (subset.every((el) => el.hasOwnProperty(key) && Object.getOwnPropertyDescriptor(el, key).enumerable)) {
128
- propertiesList.push(key);
124
+ if (el.properties) {
125
+ el.properties.list().forEach((key) => {
126
+ if (propertiesList.includes(key) === false) {
127
+ if (subset.every((sub) => sub.properties?.has(key))) {
128
+ propertiesList.push(key);
129
+ }
129
130
  }
130
- }
131
- });
131
+ });
132
+ }
132
133
  });
133
134
 
134
135
  return propertiesList;
135
136
  }
136
137
 
137
138
 
139
+ /**
140
+ * Get the Property descriptor for a named property from a representative selected entity.
141
+ * @param {string} entityType
142
+ * @param {string} property
143
+ * @return {Property|undefined}
144
+ */
145
+ getEntityPropertyDefinition(entityType, property) {
146
+ const index = DesignCore.Scene.selectionManager.selectionSet.selectionSet.find((i) => {
147
+ const entity = DesignCore.Scene.entities.get(i);
148
+ return (entityType === 'All' || entity.type === entityType) && entity.properties?.has(property);
149
+ });
150
+ if (index === undefined) return undefined;
151
+ return DesignCore.Scene.entities.get(index).properties.definition(property);
152
+ }
153
+
138
154
  /**
139
155
  * Get a list the property values
140
- * @param {string} itemType
156
+ * @param {string} entityType
141
157
  * @param {string} property
142
158
  * @return {Array}
143
159
  */
144
- getItemPropertyValue(itemType, property) {
160
+ getEntityPropertyValue(entityType, property) {
145
161
  // Loop through the items and get a list the property values
146
162
  const propertiesValueList = [];
147
163
  if (DesignCore.Scene.selectionManager.selectionSet.selectionSet.length > 0) {
148
164
  for (let i = 0; i < DesignCore.Scene.selectionManager.selectionSet.selectionSet.length; i++) {
149
- if (DesignCore.Scene.entities.get(DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]).type === itemType || itemType === 'All') {
150
- const prop = DesignCore.Scene.entities.get(DesignCore.Scene.selectionManager.selectionSet.selectionSet[i])[property];
151
- propertiesValueList.push(prop);
165
+ if (DesignCore.Scene.entities.get(DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]).type === entityType || entityType === 'All') {
166
+ const entity = DesignCore.Scene.entities.get(DesignCore.Scene.selectionManager.selectionSet.selectionSet[i]);
167
+ propertiesValueList.push(entity.getProperty(property));
152
168
  }
153
169
  }
154
170
  }
155
171
 
156
- // Check if every item in the selection set has the same value for the property
172
+ // Check if every entity in the selection set has the same value for the property
157
173
  if (propertiesValueList.every((prop) => {
158
174
  return prop === propertiesValueList[0];
159
175
  })) {
@@ -8,9 +8,11 @@ import { Input, PromptOptions } from '../lib/inputManager.js';
8
8
  import { Flags } from '../properties/flags.js';
9
9
  import { Property } from '../properties/property.js';
10
10
  import { AddState, RemoveState } from '../lib/stateManager.js';
11
+ import { Logging } from '../lib/logging.js';
12
+ import { Utils } from '../lib/utils.js';
11
13
 
12
14
  import { DesignCore } from '../designCore.js';
13
- import { Utils } from '../lib/utils.js';
15
+
14
16
 
15
17
  /**
16
18
  * Block Entity Class
@@ -36,7 +38,7 @@ export class Block extends Entity {
36
38
  writable: true,
37
39
  });
38
40
 
39
- Object.defineProperty(this, 'items', {
41
+ Object.defineProperty(this, 'entities', {
40
42
  value: [],
41
43
  writable: true,
42
44
  });
@@ -47,8 +49,8 @@ export class Block extends Entity {
47
49
  this.name = data.name || data[2];
48
50
  }
49
51
 
50
- if (data.hasOwnProperty('items')) {
51
- this.items = data.items;
52
+ if (data.hasOwnProperty('entities')) {
53
+ this.entities = data.entities;
52
54
  }
53
55
 
54
56
  if (data.hasOwnProperty('flags') || data.hasOwnProperty('70')) {
@@ -114,19 +116,21 @@ export class Block extends Entity {
114
116
  // array to hold state changes
115
117
  const stateChanges = [];
116
118
 
117
- // move selected items from scene to block
119
+ // move selected entities from scene to block
118
120
  selections.forEach((index) => {
119
- const item = DesignCore.Scene.entities.get(index);
120
- // remove item from scene
121
- const copyofitem = Utils.cloneObject(item);
122
- // adjust the items points to reflect the insert point
121
+ const entity = DesignCore.Scene.entities.get(index);
122
+ // remove entity from scene
123
+ const copyOfEntity = Utils.cloneObject(entity);
124
+ // assign a fresh handle — the block entity is a new entity distinct from the scene entity
125
+ copyOfEntity.setProperty('handle', DesignCore.HandleManager.next());
126
+ // adjust the entity's points to reflect the insert point
123
127
  const delta = new Point(-insertPoint.x, -insertPoint.y);
124
- if (item.hasOwnProperty('points')) {
125
- const points = copyofitem.points.map((p) => new Point(p.x, p.y, p.bulge, p.sequence).add(delta));
126
- copyofitem.setProperty('points', points);
128
+ if (copyOfEntity.points?.length) {
129
+ const points = copyOfEntity.points.map((p) => new Point(p.x, p.y, p.bulge, p.sequence).add(delta));
130
+ copyOfEntity.setProperty('points', points);
127
131
  }
128
- block.items.push(copyofitem);
129
- const stateChangeRemove = new RemoveState(item);
132
+ block.entities.push(copyOfEntity);
133
+ const stateChangeRemove = new RemoveState(entity);
130
134
  stateChanges.push(stateChangeRemove);
131
135
  });
132
136
 
@@ -161,9 +165,9 @@ export class Block extends Entity {
161
165
  */
162
166
  dxf(file) {
163
167
  file.writeGroupCode('0', 'BLOCK');
164
- file.writeGroupCode('5', this.handle, DXFFile.Version.R2000); // Handle
168
+ file.writeGroupCode('5', this.getProperty('handle'), DXFFile.Version.R2000); // Handle
165
169
  file.writeGroupCode('100', 'AcDbEntity', DXFFile.Version.R2000);
166
- file.writeGroupCode('8', this.layer);
170
+ file.writeGroupCode('8', this.getProperty('layer'));
167
171
  file.writeGroupCode('100', 'AcDbBlockBegin', DXFFile.Version.R2000);
168
172
  file.writeGroupCode('2', this.name);
169
173
  file.writeGroupCode('70', this.flags.getFlagValue());
@@ -173,8 +177,8 @@ export class Block extends Entity {
173
177
  file.writeGroupCode('3', this.name); // Name again
174
178
  file.writeGroupCode('1', '');
175
179
 
176
- for (let i = 0; i < this.items.length; i++) {
177
- this.items[i].dxf(file);
180
+ for (let i = 0; i < this.entities.length; i++) {
181
+ this.entities[i].dxf(file);
178
182
  }
179
183
 
180
184
  const endblk = new EndBlock({ handle: this.endblkHandle });
@@ -182,53 +186,18 @@ export class Block extends Entity {
182
186
  }
183
187
 
184
188
  /**
185
- * Clear items from the block
186
- */
187
- clearItems() {
188
- this.items = [];
189
- }
190
-
191
- /**
192
- * Add an item to the block
193
- * @param {Object} item
189
+ * Clear entities from the block
194
190
  */
195
- addItem(item) {
196
- this.items.push(item);
191
+ clearEntities() {
192
+ this.entities = [];
197
193
  }
198
194
 
199
195
  /**
200
- * Draw the entity
201
- * @param {Object} ctx - context
202
- * @param {number} scale
203
- * @param {Object} insert - insert entity
196
+ * Add an entity to the block
197
+ * @param {Object} entity
204
198
  */
205
- draw(ctx, scale, insert = undefined) {
206
- if (!this.items.length) {
207
- // nothing to draw
208
- return;
209
- }
210
-
211
- this.items.forEach((item) => {
212
- ctx.save();
213
- // Use the current item and block insert to set the context
214
- // insert required for colour ByBlock
215
- DesignCore.Canvas.setContext(item, ctx, insert);
216
-
217
- item.draw(ctx, scale);
218
- ctx.restore();
219
- });
220
-
221
- /*
222
- //////////////////////////////////////////
223
- // draw test point for location
224
- ctx.strokeStyle = Colours.rgbToString(colour);
225
- ctx.lineWidth = 1 / scale;
226
- ctx.beginPath()
227
- ctx.moveTo(this.points[0].x, this.points[0].y);
228
- ctx.arc(this.points[0].x, this.points[0].y, 5 / scale, radians2degrees(0), radians2degrees(360), false);
229
- ctx.stroke();
230
- //////////////////////////////////////////
231
- */
199
+ addEntity(entity) {
200
+ this.entities.push(entity);
232
201
  }
233
202
 
234
203
  /**
@@ -240,15 +209,15 @@ export class Block extends Entity {
240
209
  snaps(mousePoint, delta) {
241
210
  const snaps = [];
242
211
 
243
- if (!this.items.length) {
212
+ if (!this.entities.length) {
244
213
  // nothing to draw
245
214
  return snaps;
246
215
  }
247
216
 
248
- for (let item = 0; item < this.items.length; item++) {
249
- // collect the child item snaps
250
- const itemSnaps = this.items[item].snaps(mousePoint, delta);
251
- snaps.push(...itemSnaps);
217
+ for (let entity = 0; entity < this.entities.length; entity++) {
218
+ // collect the child entity snaps
219
+ const entitySnaps = this.entities[entity].snaps(mousePoint, delta);
220
+ snaps.push(...entitySnaps);
252
221
  }
253
222
 
254
223
  return snaps;
@@ -263,19 +232,19 @@ export class Block extends Entity {
263
232
  let distance = Infinity;
264
233
  let minPnt = P;
265
234
 
266
- if (!this.items.length) {
235
+ if (!this.entities.length) {
267
236
  // nothing to draw
268
237
  return [minPnt, distance];
269
238
  }
270
239
 
271
- for (let idx = 0; idx < this.items.length; idx++) {
272
- const itemClosestPoint = this.items[idx].closestPoint(P);
273
- const itemPnt = itemClosestPoint[0];
274
- const itemDist = itemClosestPoint[1];
240
+ for (let idx = 0; idx < this.entities.length; idx++) {
241
+ const entityClosestPoint = this.entities[idx].closestPoint(P);
242
+ const entityPnt = entityClosestPoint[0];
243
+ const entityDist = entityClosestPoint[1];
275
244
 
276
- if (itemDist < distance) {
277
- distance = itemDist;
278
- minPnt = itemPnt;
245
+ if (entityDist < distance) {
246
+ distance = entityDist;
247
+ minPnt = entityPnt;
279
248
  }
280
249
  }
281
250
 
@@ -292,13 +261,13 @@ export class Block extends Entity {
292
261
  let ymin = Infinity;
293
262
  let ymax = -Infinity;
294
263
 
295
- for (let idx = 0; idx < this.items.length; idx++) {
296
- const itemBoundingBox = this.items[idx].boundingBox();
264
+ for (let idx = 0; idx < this.entities.length; idx++) {
265
+ const entityBoundingBox = this.entities[idx].boundingBox();
297
266
 
298
- xmin = Math.min(xmin, itemBoundingBox.xMin);
299
- xmax = Math.max(xmax, itemBoundingBox.xMax);
300
- ymin = Math.min(ymin, itemBoundingBox.yMin);
301
- ymax = Math.max(ymax, itemBoundingBox.yMax);
267
+ xmin = Math.min(xmin, entityBoundingBox.xMin);
268
+ xmax = Math.max(xmax, entityBoundingBox.xMax);
269
+ ymin = Math.min(ymin, entityBoundingBox.yMin);
270
+ ymax = Math.max(ymax, entityBoundingBox.yMax);
302
271
  }
303
272
 
304
273
  const topLeft = new Point(xmin, ymax);
@@ -313,8 +282,8 @@ export class Block extends Entity {
313
282
  * @return {boolean} true if touched
314
283
  */
315
284
  touched(selection) {
316
- for (let idx = 0; idx < this.items.length; idx++) {
317
- const touched = this.items[idx].touched(selection);
285
+ for (let idx = 0; idx < this.entities.length; idx++) {
286
+ const touched = this.entities[idx].touched(selection);
318
287
  if (touched) {
319
288
  return true;
320
289
  }
@@ -321,11 +321,11 @@ export class DimStyle {
321
321
  this.DIMTMOVE = Property.loadValue([data.DIMTMOVE, data[279]], 0);
322
322
 
323
323
  // DXF Groupcode 280 - Horizontal dimension text position:
324
- // 0 = Above dimension line and center-justified between extension lines
324
+ // 0 = Above dimension line and centre-justified between extension lines
325
325
  // 1 = Above dimension line and next to first extension line
326
326
  // 2 = Above dimension line and next to second extension line
327
- // 3 = Above and center-justified to first extension line
328
- // 4 = Above and center-justified to second extension line
327
+ // 3 = Above and centre-justified to first extension line
328
+ // 4 = Above and centre-justified to second extension line
329
329
  this.DIMJUST = Property.loadValue([data.DIMJUST, data[280]], 0);
330
330
 
331
331
  // DXF Groupcode 281 - Suppression of first extension line:
@@ -506,7 +506,7 @@ export class DimStyle {
506
506
  }
507
507
 
508
508
  /**
509
- * get the DIMCEN property for the center mark size
509
+ * get the DIMCEN property for the centre mark size
510
510
  * @return {Number} DIMCEN value
511
511
  * This uses two internal values to define the DIMCEN property
512
512
  * DIMCENSTYL & DIMCENVALUE
@@ -604,7 +604,7 @@ export class DimStyle {
604
604
  file.writeGroupCode('275', this.DIMAUNIT, DXFFile.Version.R13);
605
605
  file.writeGroupCode('276', this.DIMFRAC, DXFFile.Version.R2000);
606
606
  file.writeGroupCode('277', this.DIMLUNIT, DXFFile.Version.R2000);
607
- // file.writeGroupCode('278', this.DIMDSEP, DXFFile.Version.R14)); - TODO: AutoCAD uses a numberical description
607
+ // file.writeGroupCode('278', this.DIMDSEP, DXFFile.Version.R14)); - TODO: AutoCAD uses a numerical description
608
608
  file.writeGroupCode('279', this.DIMTMOVE, DXFFile.Version.R2000);
609
609
  file.writeGroupCode('280', this.DIMJUST, DXFFile.Version.R13);
610
610
  file.writeGroupCode('281', this.DIMSD1 ? 1 : 0, DXFFile.Version.R13); // convert bool to int
@@ -20,7 +20,7 @@ export class EndBlock extends Entity {
20
20
  */
21
21
  dxf(file) {
22
22
  file.writeGroupCode('0', 'ENDBLK');
23
- file.writeGroupCode('5', this.handle, DXFFile.Version.R2000); // Handle
23
+ file.writeGroupCode('5', this.getProperty('handle'), DXFFile.Version.R2000); // Handle
24
24
  file.writeGroupCode('100', 'AcDbEntity', DXFFile.Version.R2000);
25
25
  // file.writeGroupCode('8', this.layer);
26
26
  file.writeGroupCode('100', 'AcDbBlockEnd', DXFFile.Version.R2000);
@@ -166,6 +166,14 @@ export class Layer {
166
166
  return false;
167
167
  }
168
168
 
169
+ /**
170
+ * Determine if layer is plottable (visible and plotting flag set)
171
+ * @return {boolean}
172
+ */
173
+ get isPlottable() {
174
+ return this.isVisible && this.plotting;
175
+ }
176
+
169
177
  /**
170
178
  * Determine if layer is selectable
171
179
  * @return {boolean}
@@ -48,7 +48,7 @@ export class LTypeManager extends StyleManagerBase {
48
48
  */
49
49
  dxf(file) {
50
50
  // Create table data for ltype styles
51
- // The LTYPE Table must preceed the LAYER table
51
+ // The LTYPE Table must precede the LAYER table
52
52
  file.writeGroupCode('0', 'TABLE');
53
53
  file.writeGroupCode('2', 'LTYPE');
54
54
  file.writeGroupCode('5', this.handle, DXFFile.Version.R2000);
@@ -40,7 +40,7 @@ export class StyleManagerBase extends TableManagerBase {
40
40
  const selectionSet = [];
41
41
 
42
42
  for (let i = 0; i < DesignCore.Scene.entities.count(); i++) {
43
- if (DesignCore.Scene.entities.get(i)[this.itemProperty] === style) {
43
+ if ((DesignCore.Scene.entities.get(i).getProperty?.(this.itemProperty) ?? DesignCore.Scene.entities.get(i)[this.itemProperty]) === style) {
44
44
  selectionSet.push(i);
45
45
  }
46
46
  }
@@ -79,7 +79,8 @@ export class StyleManagerBase extends TableManagerBase {
79
79
  this.addStandardItems();
80
80
 
81
81
  for (let i = 0; i < DesignCore.Scene.entities.count(); i++) {
82
- const style = (DesignCore.Scene.entities.get(i)[this.itemProperty]);
82
+ const entity = DesignCore.Scene.entities.get(i);
83
+ const style = entity.getProperty?.(this.itemProperty) ?? entity[this.itemProperty];
83
84
  this.addItem({
84
85
  'name': style,
85
86
  });
@@ -122,10 +122,15 @@ export class TableManagerBase {
122
122
  return this.getItemByName(newItemName);
123
123
  }
124
124
 
125
- if (newItem.handle === undefined) {
126
- newItem.handle = DesignCore.HandleManager.next();
125
+ const existingHandle = newItem.getProperty?.('handle') ?? newItem.handle;
126
+ if (existingHandle === undefined) {
127
+ if (newItem.setProperty) {
128
+ newItem.setProperty('handle', DesignCore.HandleManager.next());
129
+ } else {
130
+ newItem.handle = DesignCore.HandleManager.next();
131
+ }
127
132
  } else {
128
- DesignCore.HandleManager.checkHandle(newItem.handle);
133
+ DesignCore.HandleManager.checkHandle(existingHandle);
129
134
  }
130
135
 
131
136
  if (!exists) {
@@ -12,9 +12,9 @@ export class VPort {
12
12
  this.handle = Property.loadValue([data?.handle, data?.[5]]);
13
13
  // DXF Groupcode 2 - Name
14
14
  this.name = Property.loadValue([data?.name, data?.[2]], '*ACTIVE');
15
- // DXF Groupcode 12 - View center X
15
+ // DXF Groupcode 12 - View centre X
16
16
  this.viewCenterX = Property.loadValue([data?.viewCenterX, data?.[12]], 0);
17
- // DXF Groupcode 22 - View center Y
17
+ // DXF Groupcode 22 - View centre Y
18
18
  this.viewCenterY = Property.loadValue([data?.viewCenterY, data?.[22]], 0);
19
19
  // DXF Groupcode 40 - VPort height
20
20
  this.height = Property.loadValue([data?.height, data?.[40]], 0);