@cornerstonejs/tools 4.17.1 → 4.17.3

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 (30) hide show
  1. package/dist/esm/drawingSvg/draw.js +4 -0
  2. package/dist/esm/drawingSvg/drawTextBox.js +8 -4
  3. package/dist/esm/tools/annotation/AngleTool.js +15 -29
  4. package/dist/esm/tools/annotation/ArrowAnnotateTool.js +9 -28
  5. package/dist/esm/tools/annotation/BidirectionalTool.js +10 -31
  6. package/dist/esm/tools/annotation/CircleROITool.js +12 -31
  7. package/dist/esm/tools/annotation/CobbAngleTool.js +14 -32
  8. package/dist/esm/tools/annotation/EllipticalROITool.js +11 -31
  9. package/dist/esm/tools/annotation/HeightTool.js +11 -31
  10. package/dist/esm/tools/annotation/LengthTool.js +10 -30
  11. package/dist/esm/tools/annotation/LivewireContourTool.js +20 -20
  12. package/dist/esm/tools/annotation/PlanarFreehandROITool.js +8 -21
  13. package/dist/esm/tools/annotation/ProbeTool.js +3 -5
  14. package/dist/esm/tools/annotation/RectangleROITool.js +10 -30
  15. package/dist/esm/tools/annotation/SplineROITool.js +20 -20
  16. package/dist/esm/tools/annotation/UltrasoundDirectionalTool.js +15 -29
  17. package/dist/esm/tools/base/AnnotationTool.d.ts +11 -0
  18. package/dist/esm/tools/base/AnnotationTool.js +50 -0
  19. package/dist/esm/tools/segmentation/CircleROIStartEndThresholdTool.js +15 -31
  20. package/dist/esm/tools/segmentation/RectangleROIStartEndThresholdTool.js +10 -30
  21. package/dist/esm/tools/segmentation/SegmentBidirectionalTool.js +10 -32
  22. package/dist/esm/utilities/drawing/getTextBoxCoordsCanvas.d.ts +1 -1
  23. package/dist/esm/utilities/drawing/getTextBoxCoordsCanvas.js +113 -3
  24. package/dist/esm/utilities/drawing/textBoxOverlapRegistry.d.ts +9 -0
  25. package/dist/esm/utilities/drawing/textBoxOverlapRegistry.js +20 -0
  26. package/dist/esm/version.d.ts +1 -1
  27. package/dist/esm/version.js +1 -1
  28. package/package.json +3 -3
  29. package/dist/esm/tools/segmentation/strategies/__tests__/fillCircle.spec.d.ts +0 -1
  30. package/dist/esm/tools/segmentation/strategies/__tests__/fillCircle.spec.js +0 -27
@@ -14,8 +14,6 @@ import registerOpenContourEditLoop from './planarFreehandROITool/openContourEdit
14
14
  import registerOpenContourEndEditLoop from './planarFreehandROITool/openContourEndEditLoop';
15
15
  import registerRenderMethods from './planarFreehandROITool/renderMethods';
16
16
  import { triggerAnnotationModified } from '../../stateManagement/annotation/helpers/state';
17
- import { drawLinkedTextBox } from '../../drawingSvg';
18
- import { getTextBoxCoordsCanvas } from '../../utilities/drawing';
19
17
  import { getLineSegmentIntersectionsCoordinates } from '../../utilities/math/polyline';
20
18
  import { isViewportPreScaled } from '../../utilities/viewport/isViewportPreScaled';
21
19
  import { BasicStatsCalculator } from '../../utilities/math/basic';
@@ -213,30 +211,19 @@ class PlanarFreehandROITool extends ContourSegmentationBaseTool {
213
211
  viewportId: enabledElement.viewport.id,
214
212
  annotationUID: annotation.annotationUID,
215
213
  };
216
- const options = this.getLinkedTextBoxStyle(styleSpecifier, annotation);
217
- if (!options.visibility) {
218
- return;
219
- }
220
214
  const textLines = this.configuration.getTextLines(data, targetId);
221
215
  if (!textLines || textLines.length === 0) {
222
216
  return;
223
217
  }
224
218
  const canvasCoordinates = data.contour.polyline.map((p) => viewport.worldToCanvas(p));
225
- if (!data.handles.textBox.hasMoved) {
226
- const canvasTextBoxCoords = getTextBoxCoordsCanvas(canvasCoordinates);
227
- data.handles.textBox.worldPosition =
228
- viewport.canvasToWorld(canvasTextBoxCoords);
229
- }
230
- const textBoxPosition = viewport.worldToCanvas(data.handles.textBox.worldPosition);
231
- const textBoxUID = '1';
232
- const boundingBox = drawLinkedTextBox(svgDrawingHelper, annotation.annotationUID ?? '', textBoxUID, textLines, textBoxPosition, canvasCoordinates, {}, options);
233
- const { x: left, y: top, width, height } = boundingBox;
234
- data.handles.textBox.worldBoundingBox = {
235
- topLeft: viewport.canvasToWorld([left, top]),
236
- topRight: viewport.canvasToWorld([left + width, top]),
237
- bottomLeft: viewport.canvasToWorld([left, top + height]),
238
- bottomRight: viewport.canvasToWorld([left + width, top + height]),
239
- };
219
+ this.renderLinkedTextBoxAnnotation({
220
+ enabledElement,
221
+ svgDrawingHelper,
222
+ annotation,
223
+ styleSpecifier,
224
+ textLines,
225
+ canvasCoordinates,
226
+ });
240
227
  };
241
228
  registerDrawLoop(this);
242
229
  registerEditLoopCommon(this);
@@ -5,6 +5,7 @@ import { addAnnotation, getAnnotations, removeAnnotation, } from '../../stateMan
5
5
  import { triggerAnnotationCompleted, triggerAnnotationModified, } from '../../stateManagement/annotation/helpers/state';
6
6
  import { getCalibratedProbeUnitsAndValue } from '../../utilities/getCalibratedUnits';
7
7
  import { drawHandles as drawHandlesSvg, drawTextBox as drawTextBoxSvg, } from '../../drawingSvg';
8
+ import { getTextBoxCoordsCanvas } from '../../utilities/drawing';
8
9
  import { state } from '../../store/state';
9
10
  import { ChangeTypes, Events } from '../../enums';
10
11
  import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
@@ -207,12 +208,9 @@ class ProbeTool extends AnnotationTool {
207
208
  }
208
209
  const textLines = this.configuration.getTextLines(data, targetId);
209
210
  if (textLines) {
210
- const textCanvasCoordinates = [
211
- canvasCoordinates[0] + this.configuration.textCanvasOffset.x,
212
- canvasCoordinates[1] + this.configuration.textCanvasOffset.y,
213
- ];
211
+ const textCanvasCoordinates = getTextBoxCoordsCanvas([canvasCoordinates], element, textLines);
214
212
  const textUID = '0';
215
- drawTextBoxSvg(svgDrawingHelper, annotationUID, textUID, textLines, [textCanvasCoordinates[0], textCanvasCoordinates[1]], options);
213
+ drawTextBoxSvg(svgDrawingHelper, annotationUID, textUID, textLines, textCanvasCoordinates, options);
216
214
  }
217
215
  }
218
216
  return renderStatus;
@@ -7,12 +7,11 @@ import { addAnnotation, getAnnotations, removeAnnotation, } from '../../stateMan
7
7
  import { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking';
8
8
  import { isAnnotationVisible } from '../../stateManagement/annotation/annotationVisibility';
9
9
  import { triggerAnnotationCompleted, triggerAnnotationModified, } from '../../stateManagement/annotation/helpers/state';
10
- import { drawHandles as drawHandlesSvg, drawLinkedTextBox as drawLinkedTextBoxSvg, drawRectByCoordinates as drawRectSvg, } from '../../drawingSvg';
10
+ import { drawHandles as drawHandlesSvg, drawRectByCoordinates as drawRectSvg, } from '../../drawingSvg';
11
11
  import { state } from '../../store/state';
12
12
  import { ChangeTypes, Events } from '../../enums';
13
13
  import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
14
14
  import * as rectangle from '../../utilities/math/rectangle';
15
- import { getTextBoxCoordsCanvas } from '../../utilities/drawing';
16
15
  import { resetElementCursor, hideElementCursor, } from '../../cursors/elementCursor';
17
16
  import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds';
18
17
  import { getPixelValueUnits } from '../../utilities/getPixelValueUnits';
@@ -396,39 +395,20 @@ class RectangleROITool extends AnnotationTool {
396
395
  lineWidth,
397
396
  }, dataId);
398
397
  renderStatus = true;
399
- const options = this.getLinkedTextBoxStyle(styleSpecifier, annotation);
400
- if (!options.visibility) {
401
- data.handles.textBox = {
402
- hasMoved: false,
403
- worldPosition: [0, 0, 0],
404
- worldBoundingBox: {
405
- topLeft: [0, 0, 0],
406
- topRight: [0, 0, 0],
407
- bottomLeft: [0, 0, 0],
408
- bottomRight: [0, 0, 0],
409
- },
410
- };
411
- continue;
412
- }
413
398
  const textLines = this.configuration.getTextLines(data, targetId);
414
399
  if (!textLines || textLines.length === 0) {
415
400
  continue;
416
401
  }
417
- if (!data.handles.textBox.hasMoved) {
418
- const canvasTextBoxCoords = getTextBoxCoordsCanvas(canvasCoordinates);
419
- data.handles.textBox.worldPosition =
420
- viewport.canvasToWorld(canvasTextBoxCoords);
402
+ if (!this.renderLinkedTextBoxAnnotation({
403
+ enabledElement,
404
+ svgDrawingHelper,
405
+ annotation,
406
+ styleSpecifier,
407
+ textLines,
408
+ canvasCoordinates,
409
+ })) {
410
+ continue;
421
411
  }
422
- const textBoxPosition = viewport.worldToCanvas(data.handles.textBox.worldPosition);
423
- const textBoxUID = '1';
424
- const boundingBox = drawLinkedTextBoxSvg(svgDrawingHelper, annotationUID, textBoxUID, textLines, textBoxPosition, canvasCoordinates, {}, options);
425
- const { x: left, y: top, width, height } = boundingBox;
426
- data.handles.textBox.worldBoundingBox = {
427
- topLeft: viewport.canvasToWorld([left, top]),
428
- topRight: viewport.canvasToWorld([left + width, top]),
429
- bottomLeft: viewport.canvasToWorld([left, top + height]),
430
- bottomRight: viewport.canvasToWorld([left + width, top + height]),
431
- };
432
412
  }
433
413
  return renderStatus;
434
414
  };
@@ -1,13 +1,12 @@
1
1
  import { getEnabledElement, eventTarget, triggerEvent, utilities, getEnabledElementByViewportId, } from '@cornerstonejs/core';
2
2
  import { vec3 } from 'gl-matrix';
3
3
  import { addAnnotation, getChildAnnotations, removeAnnotation, } from '../../stateManagement/annotation/annotationState';
4
- import { drawHandles as drawHandlesSvg, drawPolyline as drawPolylineSvg, drawLinkedTextBox as drawLinkedTextBoxSvg, } from '../../drawingSvg';
4
+ import { drawHandles as drawHandlesSvg, drawPolyline as drawPolylineSvg, } from '../../drawingSvg';
5
5
  import { state } from '../../store/state';
6
6
  import { Events, MouseBindings, KeyboardBindings, ChangeTypes, } from '../../enums';
7
7
  import * as math from '../../utilities/math';
8
8
  import throttle from '../../utilities/throttle';
9
9
  import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
10
- import { getTextBoxCoordsCanvas } from '../../utilities/drawing';
11
10
  import { getCalibratedLengthUnitsAndScale } from '../../utilities/getCalibratedUnits';
12
11
  import getMouseModifierKey from '../../eventDispatchers/shared/getMouseModifier';
13
12
  import { ContourWindingDirection } from '../../types/ContourAnnotation';
@@ -364,32 +363,33 @@ class SplineROITool extends ContourSegmentationBaseTool {
364
363
  element.removeEventListener(Events.MOUSE_DOUBLE_CLICK, this._mouseDownCallback);
365
364
  element.removeEventListener(Events.TOUCH_TAP, this._mouseDownCallback);
366
365
  };
367
- this._renderStats = (annotation, viewport, svgDrawingHelper, textboxStyle) => {
366
+ this._renderStats = (annotation, enabledElement, svgDrawingHelper) => {
368
367
  const data = annotation.data;
368
+ const { viewport } = enabledElement;
369
369
  const targetId = this.getTargetId(viewport);
370
- if (!data.spline.instance.closed || !textboxStyle.visibility) {
370
+ if (!data.spline.instance.closed) {
371
371
  return;
372
372
  }
373
+ const styleSpecifier = {
374
+ toolGroupId: this.toolGroupId,
375
+ toolName: this.getToolName(),
376
+ viewportId: enabledElement.viewport.id,
377
+ annotationUID: annotation.annotationUID,
378
+ };
373
379
  const textLines = this.configuration.getTextLines(data, targetId);
374
380
  if (!textLines || textLines.length === 0) {
375
381
  return;
376
382
  }
377
383
  const canvasCoordinates = data.handles.points.map((p) => viewport.worldToCanvas(p));
378
- if (!data.handles.textBox.hasMoved) {
379
- const canvasTextBoxCoords = getTextBoxCoordsCanvas(canvasCoordinates);
380
- data.handles.textBox.worldPosition =
381
- viewport.canvasToWorld(canvasTextBoxCoords);
382
- }
383
- const textBoxPosition = viewport.worldToCanvas(data.handles.textBox.worldPosition);
384
- const textBoxUID = 'textBox';
385
- const boundingBox = drawLinkedTextBoxSvg(svgDrawingHelper, annotation.annotationUID ?? '', textBoxUID, textLines, textBoxPosition, canvasCoordinates, {}, textboxStyle);
386
- const { x: left, y: top, width, height } = boundingBox;
387
- data.handles.textBox.worldBoundingBox = {
388
- topLeft: viewport.canvasToWorld([left, top]),
389
- topRight: viewport.canvasToWorld([left + width, top]),
390
- bottomLeft: viewport.canvasToWorld([left, top + height]),
391
- bottomRight: viewport.canvasToWorld([left + width, top + height]),
392
- };
384
+ this.renderLinkedTextBoxAnnotation({
385
+ enabledElement,
386
+ svgDrawingHelper,
387
+ annotation,
388
+ styleSpecifier,
389
+ textLines,
390
+ canvasCoordinates,
391
+ textBoxUID: 'textBox',
392
+ });
393
393
  };
394
394
  this.addControlPointCallback = (evt, annotation) => {
395
395
  const { data } = annotation;
@@ -661,7 +661,7 @@ class SplineROITool extends ContourSegmentationBaseTool {
661
661
  lineWidth: 1,
662
662
  });
663
663
  }
664
- this._renderStats(annotation, viewport, svgDrawingHelper, annotationStyle.textbox);
664
+ this._renderStats(annotation, enabledElement, svgDrawingHelper);
665
665
  if (this.fireChangeOnUpdate?.annotationUID === annotationUID) {
666
666
  this.triggerChangeEvent(annotation, enabledElement, this.fireChangeOnUpdate.changeType, this.fireChangeOnUpdate.contourHoleProcessingEnabled);
667
667
  this.fireChangeOnUpdate = null;
@@ -4,7 +4,7 @@ import { AnnotationTool } from '../base';
4
4
  import throttle from '../../utilities/throttle';
5
5
  import { addAnnotation, getAnnotations, removeAnnotation, } from '../../stateManagement/annotation/annotationState';
6
6
  import { triggerAnnotationCompleted, triggerAnnotationModified, } from '../../stateManagement/annotation/helpers/state';
7
- import { drawHandle as drawHandleSvg, drawLine as drawLineSvg, drawLinkedTextBox as drawLinkedTextBoxSvg, } from '../../drawingSvg';
7
+ import { drawHandle as drawHandleSvg, drawLine as drawLineSvg, } from '../../drawingSvg';
8
8
  import { state } from '../../store/state';
9
9
  import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
10
10
  import { distanceToPoint } from '../../utilities/math/point';
@@ -308,36 +308,22 @@ class UltrasoundDirectionalTool extends AnnotationTool {
308
308
  shadow: this.configuration.shadow,
309
309
  }, dataId);
310
310
  }
311
- const options = this.getLinkedTextBoxStyle(styleSpecifier, annotation);
312
- if (!options.visibility) {
313
- data.handles.textBox = {
314
- hasMoved: false,
315
- worldPosition: [0, 0, 0],
316
- worldBoundingBox: {
317
- topLeft: [0, 0, 0],
318
- topRight: [0, 0, 0],
319
- bottomLeft: [0, 0, 0],
320
- bottomRight: [0, 0, 0],
321
- },
322
- };
323
- continue;
324
- }
325
311
  const textLines = this.configuration.getTextLines(data, targetId, this.configuration);
326
- if (!data.handles.textBox.hasMoved) {
327
- const canvasTextBoxCoords = canvasCoordinates[1];
328
- data.handles.textBox.worldPosition =
329
- viewport.canvasToWorld(canvasTextBoxCoords);
312
+ const vertexAnchor = [
313
+ canvasCoordinates[1],
314
+ canvasCoordinates[1],
315
+ ];
316
+ if (!this.renderLinkedTextBoxAnnotation({
317
+ enabledElement,
318
+ svgDrawingHelper,
319
+ annotation,
320
+ styleSpecifier,
321
+ textLines,
322
+ canvasCoordinates,
323
+ placementPoints: vertexAnchor,
324
+ })) {
325
+ continue;
330
326
  }
331
- const textBoxPosition = viewport.worldToCanvas(data.handles.textBox.worldPosition);
332
- const textBoxUID = '1';
333
- const boundingBox = drawLinkedTextBoxSvg(svgDrawingHelper, annotationUID, textBoxUID, textLines, textBoxPosition, canvasCoordinates, {}, options);
334
- const { x: left, y: top, width, height } = boundingBox;
335
- data.handles.textBox.worldBoundingBox = {
336
- topLeft: viewport.canvasToWorld([left, top]),
337
- topRight: viewport.canvasToWorld([left + width, top]),
338
- bottomLeft: viewport.canvasToWorld([left, top + height]),
339
- bottomRight: viewport.canvasToWorld([left + width, top + height]),
340
- };
341
327
  }
342
328
  return renderStatus;
343
329
  };
@@ -3,6 +3,7 @@ import type { Types } from '@cornerstonejs/core';
3
3
  import AnnotationDisplayTool from './AnnotationDisplayTool';
4
4
  import type { Annotation, Annotations, EventTypes, ToolHandle, InteractionTypes, ToolProps, PublicToolProps } from '../../types';
5
5
  import type { AnnotationStyle, StyleSpecifier } from '../../types/AnnotationStyle';
6
+ import type { SVGDrawingHelper } from '../../types';
6
7
  declare abstract class AnnotationTool extends AnnotationDisplayTool {
7
8
  protected eventDispatchDetail: {
8
9
  viewportId: string;
@@ -30,6 +31,16 @@ declare abstract class AnnotationTool extends AnnotationDisplayTool {
30
31
  mouseMoveCallback: (evt: EventTypes.MouseMoveEventType, filteredAnnotations?: Annotations) => boolean;
31
32
  getHandleNearImagePoint(element: HTMLDivElement, annotation: Annotation, canvasCoords: Types.Point2, proximity: number): ToolHandle | undefined;
32
33
  getLinkedTextBoxStyle(specifications: StyleSpecifier, annotation?: Annotation): Record<string, unknown>;
34
+ protected renderLinkedTextBoxAnnotation(options: {
35
+ enabledElement: Types.IEnabledElement;
36
+ svgDrawingHelper: SVGDrawingHelper;
37
+ annotation: Annotation;
38
+ styleSpecifier: StyleSpecifier;
39
+ textLines: string[];
40
+ canvasCoordinates: Types.Point2[];
41
+ textBoxUID?: string;
42
+ placementPoints?: Types.Point2[];
43
+ }): boolean;
33
44
  static isSuvScaled(viewport: Types.IStackViewport | Types.IVolumeViewport, targetId: string, imageId?: string): boolean;
34
45
  isSuvScaled: typeof AnnotationTool.isSuvScaled;
35
46
  protected getAnnotationStyle(context: {
@@ -5,6 +5,8 @@ import { isAnnotationLocked } from '../../stateManagement/annotation/annotationL
5
5
  import { isAnnotationVisible } from '../../stateManagement/annotation/annotationVisibility';
6
6
  import { addAnnotation, removeAnnotation, getAnnotation, } from '../../stateManagement/annotation/annotationState';
7
7
  import { triggerAnnotationModified } from '../../stateManagement/annotation/helpers/state';
8
+ import { drawLinkedTextBox } from '../../drawingSvg';
9
+ import { getTextBoxCoordsCanvas } from '../../utilities/drawing';
8
10
  import ChangeTypes from '../../enums/ChangeTypes';
9
11
  import { setAnnotationSelected } from '../../stateManagement/annotation/annotationSelection';
10
12
  import { addContourSegmentationAnnotation } from '../../utilities/contourSegmentation';
@@ -112,6 +114,54 @@ class AnnotationTool extends AnnotationDisplayTool {
112
114
  textBoxLinkLineColor: this.getStyle('textBoxLinkLineColor', specifications, annotation),
113
115
  };
114
116
  }
117
+ renderLinkedTextBoxAnnotation(options) {
118
+ const { enabledElement, svgDrawingHelper, annotation, styleSpecifier, textLines, canvasCoordinates, textBoxUID = '1', placementPoints, } = options;
119
+ const { viewport } = enabledElement;
120
+ const { element } = viewport;
121
+ const { annotationUID, data } = annotation;
122
+ const styleOptions = this.getLinkedTextBoxStyle(styleSpecifier, annotation);
123
+ if (!styleOptions.visibility) {
124
+ data.handles.textBox = {
125
+ hasMoved: false,
126
+ worldPosition: [0, 0, 0],
127
+ worldBoundingBox: {
128
+ topLeft: [0, 0, 0],
129
+ topRight: [0, 0, 0],
130
+ bottomLeft: [0, 0, 0],
131
+ bottomRight: [0, 0, 0],
132
+ },
133
+ };
134
+ return false;
135
+ }
136
+ if (!data.handles.textBox) {
137
+ data.handles.textBox = {
138
+ hasMoved: false,
139
+ worldPosition: [0, 0, 0],
140
+ worldBoundingBox: {
141
+ topLeft: [0, 0, 0],
142
+ topRight: [0, 0, 0],
143
+ bottomLeft: [0, 0, 0],
144
+ bottomRight: [0, 0, 0],
145
+ },
146
+ };
147
+ }
148
+ const pointsForPlacement = placementPoints ?? canvasCoordinates;
149
+ if (!data.handles.textBox.hasMoved) {
150
+ const canvasTextBoxCoords = getTextBoxCoordsCanvas(pointsForPlacement, element, textLines);
151
+ data.handles.textBox.worldPosition =
152
+ viewport.canvasToWorld(canvasTextBoxCoords);
153
+ }
154
+ const textBoxPosition = viewport.worldToCanvas(data.handles.textBox.worldPosition);
155
+ const boundingBox = drawLinkedTextBox(svgDrawingHelper, annotationUID, textBoxUID, textLines, textBoxPosition, canvasCoordinates, {}, styleOptions);
156
+ const { x: left, y: top, width, height } = boundingBox;
157
+ data.handles.textBox.worldBoundingBox = {
158
+ topLeft: viewport.canvasToWorld([left, top]),
159
+ topRight: viewport.canvasToWorld([left + width, top]),
160
+ bottomLeft: viewport.canvasToWorld([left, top + height]),
161
+ bottomRight: viewport.canvasToWorld([left + width, top + height]),
162
+ };
163
+ return true;
164
+ }
115
165
  static isSuvScaled(viewport, targetId, imageId) {
116
166
  if (viewport instanceof BaseVolumeViewport) {
117
167
  const volumeId = csUtils.getVolumeId(targetId);
@@ -2,10 +2,9 @@ import { StackViewport, cache, getEnabledElement, utilities as csUtils, utilitie
2
2
  import { vec3 } from 'gl-matrix';
3
3
  import { addAnnotation, removeAnnotation, getAnnotations, } from '../../stateManagement/annotation/annotationState';
4
4
  import { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking';
5
- import { drawCircle as drawCircleSvg, drawHandles as drawHandlesSvg, drawLinkedTextBox as drawLinkedTextBoxSvg, } from '../../drawingSvg';
5
+ import { drawCircle as drawCircleSvg, drawHandles as drawHandlesSvg, } from '../../drawingSvg';
6
6
  import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
7
7
  import getWorldWidthAndHeightFromTwoPoints from '../../utilities/planar/getWorldWidthAndHeightFromTwoPoints';
8
- import { getTextBoxCoordsCanvas } from '../../utilities/drawing';
9
8
  import throttle from '../../utilities/throttle';
10
9
  import debounce from '../../utilities/debounce';
11
10
  import { isAnnotationVisible } from '../../stateManagement/annotation/annotationVisibility';
@@ -279,40 +278,25 @@ class CircleROIStartEndThresholdTool extends CircleROITool {
279
278
  }
280
279
  renderStatus = true;
281
280
  if (this.configuration.showTextBox) {
282
- const options = this.getLinkedTextBoxStyle(styleSpecifier, annotation);
283
- if (!options.visibility) {
284
- data.handles.textBox = {
285
- hasMoved: false,
286
- worldPosition: [0, 0, 0],
287
- worldBoundingBox: {
288
- topLeft: [0, 0, 0],
289
- topRight: [0, 0, 0],
290
- bottomLeft: [0, 0, 0],
291
- bottomRight: [0, 0, 0],
292
- },
293
- };
294
- continue;
295
- }
296
281
  const textLines = this.configuration.getTextLines(data, { metadata });
297
282
  if (!textLines || textLines.length === 0) {
298
283
  continue;
299
284
  }
300
- let canvasTextBoxCoords;
301
- if (!data.handles.textBox.hasMoved) {
302
- canvasTextBoxCoords = getTextBoxCoordsCanvas(canvasCorners);
303
- data.handles.textBox.worldPosition =
304
- viewport.canvasToWorld(canvasTextBoxCoords);
285
+ const linkAnchorPoints = [
286
+ canvasCoordinates[0],
287
+ canvasCoordinates[1],
288
+ ];
289
+ if (!this.renderLinkedTextBoxAnnotation({
290
+ enabledElement,
291
+ svgDrawingHelper,
292
+ annotation,
293
+ styleSpecifier,
294
+ textLines,
295
+ canvasCoordinates: linkAnchorPoints,
296
+ placementPoints: canvasCorners,
297
+ })) {
298
+ continue;
305
299
  }
306
- const textBoxPosition = viewport.worldToCanvas(data.handles.textBox.worldPosition);
307
- const textBoxUID = '1';
308
- const boundingBox = drawLinkedTextBoxSvg(svgDrawingHelper, annotationUID, textBoxUID, textLines, textBoxPosition, [canvasCoordinates[0], canvasCoordinates[1]], {}, options);
309
- const { x: left, y: top, width, height } = boundingBox;
310
- data.handles.textBox.worldBoundingBox = {
311
- topLeft: viewport.canvasToWorld([left, top]),
312
- topRight: viewport.canvasToWorld([left + width, top]),
313
- bottomLeft: viewport.canvasToWorld([left, top + height]),
314
- bottomRight: viewport.canvasToWorld([left + width, top + height]),
315
- };
316
300
  }
317
301
  }
318
302
  return renderStatus;
@@ -3,11 +3,10 @@ import { getCalibratedLengthUnitsAndScale } from '../../utilities/getCalibratedU
3
3
  import { vec3 } from 'gl-matrix';
4
4
  import { addAnnotation, getAnnotations, removeAnnotation, } from '../../stateManagement';
5
5
  import { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking';
6
- import { drawHandles as drawHandlesSvg, drawRect as drawRectSvg, drawLinkedTextBox as drawLinkedTextBoxSvg, } from '../../drawingSvg';
6
+ import { drawHandles as drawHandlesSvg, drawRect as drawRectSvg, } from '../../drawingSvg';
7
7
  import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
8
8
  import throttle from '../../utilities/throttle';
9
9
  import debounce from '../../utilities/debounce';
10
- import { getTextBoxCoordsCanvas } from '../../utilities/drawing';
11
10
  import getWorldWidthAndHeightFromCorners from '../../utilities/planar/getWorldWidthAndHeightFromCorners';
12
11
  import { isAnnotationVisible } from '../../stateManagement/annotation/annotationVisibility';
13
12
  import { hideElementCursor, resetElementCursor, } from '../../cursors/elementCursor';
@@ -240,39 +239,20 @@ class RectangleROIStartEndThresholdTool extends RectangleROITool {
240
239
  });
241
240
  renderStatus = true;
242
241
  if (this.configuration.showTextBox) {
243
- const options = this.getLinkedTextBoxStyle(styleSpecifier, annotation);
244
- if (!options.visibility) {
245
- data.handles.textBox = {
246
- hasMoved: false,
247
- worldPosition: [0, 0, 0],
248
- worldBoundingBox: {
249
- topLeft: [0, 0, 0],
250
- topRight: [0, 0, 0],
251
- bottomLeft: [0, 0, 0],
252
- bottomRight: [0, 0, 0],
253
- },
254
- };
255
- continue;
256
- }
257
242
  const textLines = this.configuration.getTextLines(data, { metadata });
258
243
  if (!textLines || textLines.length === 0) {
259
244
  continue;
260
245
  }
261
- if (!data.handles.textBox.hasMoved) {
262
- const canvasTextBoxCoords = getTextBoxCoordsCanvas(canvasCoordinates);
263
- data.handles.textBox.worldPosition =
264
- viewport.canvasToWorld(canvasTextBoxCoords);
246
+ if (!this.renderLinkedTextBoxAnnotation({
247
+ enabledElement,
248
+ svgDrawingHelper,
249
+ annotation,
250
+ styleSpecifier,
251
+ textLines,
252
+ canvasCoordinates,
253
+ })) {
254
+ continue;
265
255
  }
266
- const textBoxPosition = viewport.worldToCanvas(data.handles.textBox.worldPosition);
267
- const textBoxUID = '1';
268
- const boundingBox = drawLinkedTextBoxSvg(svgDrawingHelper, annotationUID, textBoxUID, textLines, textBoxPosition, canvasCoordinates, {}, options);
269
- const { x: left, y: top, width, height } = boundingBox;
270
- data.handles.textBox.worldBoundingBox = {
271
- topLeft: viewport.canvasToWorld([left, top]),
272
- topRight: viewport.canvasToWorld([left + width, top]),
273
- bottomLeft: viewport.canvasToWorld([left, top + height]),
274
- bottomRight: viewport.canvasToWorld([left + width, top + height]),
275
- };
276
256
  }
277
257
  }
278
258
  return renderStatus;
@@ -2,9 +2,8 @@ import { getEnabledElement, utilities as csUtils, getEnabledElementByViewportId,
2
2
  import { addAnnotation, getAllAnnotations, getAnnotations, removeAnnotation, } from '../../stateManagement/annotation/annotationState';
3
3
  import { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking';
4
4
  import { isAnnotationVisible } from '../../stateManagement/annotation/annotationVisibility';
5
- import { drawLine as drawLineSvg, drawHandles as drawHandlesSvg, drawLinkedTextBox as drawLinkedTextBoxSvg, } from '../../drawingSvg';
5
+ import { drawLine as drawLineSvg, drawHandles as drawHandlesSvg, } from '../../drawingSvg';
6
6
  import { getViewportIdsWithToolToRender } from '../../utilities/viewportFilters';
7
- import { getTextBoxCoordsCanvas } from '../../utilities/drawing';
8
7
  import { hideElementCursor } from '../../cursors/elementCursor';
9
8
  import triggerAnnotationRenderForViewportIds from '../../utilities/triggerAnnotationRenderForViewportIds';
10
9
  import BidirectionalTool from '../annotation/BidirectionalTool';
@@ -94,41 +93,20 @@ class SegmentBidirectionalTool extends BidirectionalTool {
94
93
  shadow,
95
94
  }, dataId2);
96
95
  renderStatus = true;
97
- const options = this.getLinkedTextBoxStyle(styleSpecifier, annotation);
98
- if (!options.visibility) {
99
- data.handles.textBox = {
100
- hasMoved: false,
101
- worldPosition: [0, 0, 0],
102
- worldBoundingBox: {
103
- topLeft: [0, 0, 0],
104
- topRight: [0, 0, 0],
105
- bottomLeft: [0, 0, 0],
106
- bottomRight: [0, 0, 0],
107
- },
108
- };
109
- continue;
110
- }
111
- options.color = color;
112
96
  const textLines = this.configuration.getTextLines(data, targetId);
113
97
  if (!textLines || textLines.length === 0) {
114
98
  continue;
115
99
  }
116
- let canvasTextBoxCoords;
117
- if (!data.handles.textBox.hasMoved) {
118
- canvasTextBoxCoords = getTextBoxCoordsCanvas(canvasCoordinates);
119
- data.handles.textBox.worldPosition =
120
- viewport.canvasToWorld(canvasTextBoxCoords);
100
+ if (!this.renderLinkedTextBoxAnnotation({
101
+ enabledElement,
102
+ svgDrawingHelper,
103
+ annotation,
104
+ styleSpecifier,
105
+ textLines,
106
+ canvasCoordinates,
107
+ })) {
108
+ continue;
121
109
  }
122
- const textBoxPosition = viewport.worldToCanvas(data.handles.textBox.worldPosition);
123
- const textBoxUID = '1';
124
- const boundingBox = drawLinkedTextBoxSvg(svgDrawingHelper, annotationUID, textBoxUID, textLines, textBoxPosition, canvasCoordinates, {}, options);
125
- const { x: left, y: top, width, height } = boundingBox;
126
- data.handles.textBox.worldBoundingBox = {
127
- topLeft: viewport.canvasToWorld([left, top]),
128
- topRight: viewport.canvasToWorld([left + width, top]),
129
- bottomLeft: viewport.canvasToWorld([left, top + height]),
130
- bottomRight: viewport.canvasToWorld([left + width, top + height]),
131
- };
132
110
  }
133
111
  return renderStatus;
134
112
  };
@@ -1,2 +1,2 @@
1
1
  import type { Types } from '@cornerstonejs/core';
2
- export default function getTextBoxCoordsCanvas(annotationCanvasPoints: Array<Types.Point2>): Types.Point2;
2
+ export default function getTextBoxCoordsCanvas(annotationCanvasPoints: Array<Types.Point2>, element?: HTMLDivElement, textLines?: Array<string>): Types.Point2;