File size: 30,636 Bytes
2409829
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
use crate::consts::COLOR_OVERLAY_BLUE;
use crate::messages::portfolio::document::overlays::utility_types::{OverlayContext, Pivot};
use crate::messages::tool::tool_messages::tool_prelude::*;
use graphene_std::renderer::Rect;

/// Draws a dashed line between two points transformed by the given affine transformation.
fn draw_dashed_line(line_start: DVec2, line_end: DVec2, transform: DAffine2, overlay_context: &mut OverlayContext) {
	let min_viewport = transform.transform_point2(line_start);
	let max_viewport = transform.transform_point2(line_end);

	overlay_context.dashed_line(min_viewport, max_viewport, None, None, Some(2.), Some(2.), Some(0.5));
}

/// Draws a solid line with a length annotation between two points transformed by the given affine transformations.
fn draw_line_with_length(line_start: DVec2, line_end: DVec2, transform: DAffine2, document_to_viewport: DAffine2, overlay_context: &mut OverlayContext, label_alignment: LabelAlignment) {
	let transform_to_document = document_to_viewport.inverse() * transform;
	let min_viewport = transform.transform_point2(line_start);
	let max_viewport = transform.transform_point2(line_end);

	overlay_context.line(min_viewport, max_viewport, None, None);

	// Remove trailing zeros from the formatted string
	let length = format!("{:.2}", transform_to_document.transform_vector2(line_end - line_start).length())
		.trim_end_matches('0')
		.trim_end_matches('.')
		.to_string();

	const TOLERANCE: f64 = 0.01;
	if transform_to_document.transform_vector2(line_end - line_start).length() >= TOLERANCE {
		const TEXT_PADDING: f64 = 5.;
		// Calculate midpoint of the line
		let midpoint = (min_viewport + max_viewport) / 2.;

		// Adjust text position based on line orientation and flags
		// Determine text position based on line orientation and flags
		let (pivot_x, pivot_y) = match (label_alignment.is_vertical_line, label_alignment.text_on_left, label_alignment.text_on_top) {
			(true, true, _) => (Pivot::End, Pivot::Middle),     // Vertical line, text on the left
			(true, false, _) => (Pivot::Start, Pivot::Middle),  // Vertical line, text on the right
			(false, _, true) => (Pivot::Middle, Pivot::End),    // Horizontal line, text on top
			(false, _, false) => (Pivot::Middle, Pivot::Start), // Horizontal line, text on bottom
		};
		overlay_context.text(&length, COLOR_OVERLAY_BLUE, None, DAffine2::from_translation(midpoint), TEXT_PADDING, [pivot_x, pivot_y]);
	}
}

/// Draws a dashed outline around a rectangle to visualize the AABB
fn draw_dashed_rect_outline(rect: Rect, transform: DAffine2, overlay_context: &mut OverlayContext) {
	let min = rect.min();
	let max = rect.max();

	// Create the four corners of the rectangle
	let top_left = transform.transform_point2(DVec2::new(min.x, min.y));
	let top_right = transform.transform_point2(DVec2::new(max.x, min.y));
	let bottom_right = transform.transform_point2(DVec2::new(max.x, max.y));
	let bottom_left = transform.transform_point2(DVec2::new(min.x, max.y));

	// Draw the four sides as dashed lines
	draw_dashed_line(top_left, top_right, transform, overlay_context);
	draw_dashed_line(top_right, bottom_right, transform, overlay_context);
	draw_dashed_line(bottom_right, bottom_left, transform, overlay_context);
	draw_dashed_line(bottom_left, top_left, transform, overlay_context);
}

/// Checks if the selected bounds overlap with the hovered bounds on the Y-axis.
fn does_overlap_y(selected_bounds: Rect, hovered_bounds: Rect) -> bool {
	selected_bounds.min().x <= hovered_bounds.max().x && selected_bounds.max().x >= hovered_bounds.min().x
}

/// Checks if the selected bounds overlap with the hovered bounds on the X-axis.
fn does_overlap_x(selected_bounds: Rect, hovered_bounds: Rect) -> bool {
	selected_bounds.min().y <= hovered_bounds.max().y && selected_bounds.max().y >= hovered_bounds.min().y
}

/// Draws measurements when both X and Y axes are involved in the overlap between selected and hovered bounds.
fn draw_zero_axis_crossings(selected_bounds: Rect, hovered_bounds: Rect, transform: DAffine2, document_to_viewport: DAffine2, overlay_context: &mut OverlayContext) {
	let (selected_min, selected_max) = (selected_bounds.min(), selected_bounds.max());
	let (hovered_min, hovered_max) = (hovered_bounds.min(), hovered_bounds.max());

	let selected_on_right = selected_min.x > hovered_max.x;
	let selected_on_bottom = selected_min.y > hovered_max.y;

	let selected_y = if selected_on_bottom { selected_min.y } else { selected_max.y };
	let hovered_y = if selected_on_bottom { hovered_max.y } else { hovered_min.y };
	let selected_x = if selected_on_right { selected_min.x } else { selected_max.x };
	let hovered_x = if selected_on_right { hovered_max.x } else { hovered_min.x };

	// Draw horizontal solid line with length
	let line_start = DVec2::new(selected_x, selected_y);
	let line_end = DVec2::new(hovered_x, selected_y);
	let label_alignment = LabelAlignment::new(false, false, !selected_on_bottom);
	draw_line_with_length(line_start, line_end, transform, document_to_viewport, overlay_context, label_alignment);

	// Draw horizontal dashed line
	let line_start = DVec2::new(selected_x, hovered_y);
	let line_end = DVec2::new(hovered_x, hovered_y);
	draw_dashed_line(line_start, line_end, transform, overlay_context);

	// Draw vertical solid line with length
	let line_start = DVec2::new(selected_x, selected_y);
	let line_end = DVec2::new(selected_x, hovered_y);
	let label_alignment = LabelAlignment::new(true, !selected_on_right, false);
	draw_line_with_length(line_start, line_end, transform, document_to_viewport, overlay_context, label_alignment);

	// Draw vertical dashed line
	let line_start = DVec2::new(hovered_x, selected_y);
	let line_end = DVec2::new(hovered_x, hovered_y);
	draw_dashed_line(line_start, line_end, transform, overlay_context);
}

/// Draws measurements when only one axis is involved in the overlap between selected and hovered bounds.
fn draw_single_axis_zero_crossings(selected_bounds: Rect, hovered_bounds: Rect, transform: DAffine2, document_to_viewport: DAffine2, overlay_context: &mut OverlayContext) {
	let (selected_min, selected_max) = (selected_bounds.min(), selected_bounds.max());
	let (hovered_min, hovered_max) = (hovered_bounds.min(), hovered_bounds.max());

	let overlap_y = does_overlap_y(selected_bounds, hovered_bounds) || does_overlap_y(hovered_bounds, selected_bounds);
	let overlap_x = does_overlap_x(selected_bounds, hovered_bounds) || does_overlap_x(hovered_bounds, selected_bounds);

	let selected_on_bottom = selected_bounds.center().y > hovered_bounds.center().y;
	let selected_on_right = selected_bounds.center().x > hovered_bounds.center().x;
	if overlap_y {
		let selected_facing_edge = if hovered_max.y < selected_min.y { selected_min.y } else { selected_max.y };
		let hovered_facing_edge = if hovered_max.y < selected_min.y { hovered_max.y } else { hovered_min.y };
		let vertical_line_start_x = if hovered_max.x > selected_max.x { selected_max.x } else { selected_min.x };
		let dashed_vertical_line_start_x = if hovered_max.x > selected_max.x { hovered_min.x } else { hovered_max.x };

		// Draw horizontal solid line with length
		let line_start = DVec2::new(f64::min(hovered_max.x, selected_max.x), selected_facing_edge);
		let line_end = DVec2::new(f64::max(hovered_min.x, selected_min.x), selected_facing_edge);
		let label_alignment = LabelAlignment::new(false, false, selected_on_bottom);
		draw_line_with_length(line_start, line_end, transform, document_to_viewport, overlay_context, label_alignment);

		// Draw vertical solid line with length
		let line_start = DVec2::new(vertical_line_start_x, selected_facing_edge);
		let line_end = DVec2::new(vertical_line_start_x, hovered_facing_edge);
		let label_alignment = LabelAlignment::new(true, !selected_on_right, false);
		draw_line_with_length(line_start, line_end, transform, document_to_viewport, overlay_context, label_alignment);

		// Draw vertical dashed line
		let dashed_line_start = DVec2::new(dashed_vertical_line_start_x, selected_facing_edge);
		let dashed_line_end = DVec2::new(dashed_vertical_line_start_x, hovered_facing_edge);
		draw_dashed_line(dashed_line_start, dashed_line_end, transform, overlay_context);
	} else if overlap_x {
		let selected_facing_edge = if hovered_max.x < selected_min.x { selected_min.x } else { selected_max.x };
		let hovered_facing_edge = if hovered_max.x < selected_min.x { hovered_max.x } else { hovered_min.x };
		let horizontal_line_start_y = if hovered_max.y > selected_max.y { selected_max.y } else { selected_min.y };
		let dashed_horizontal_line_start_y = if hovered_max.y > selected_max.y { hovered_min.y } else { hovered_max.y };

		// Draw vertical solid line with length
		let line_start = DVec2::new(selected_facing_edge, f64::min(hovered_max.y, selected_max.y));
		let line_end = DVec2::new(selected_facing_edge, f64::max(hovered_min.y, selected_min.y));
		let label_alignment = LabelAlignment::new(true, selected_on_right, false);
		draw_line_with_length(line_start, line_end, transform, document_to_viewport, overlay_context, label_alignment);

		// Draw horizontal solid line with length
		let line_start = DVec2::new(selected_facing_edge, horizontal_line_start_y);
		let line_end = DVec2::new(hovered_facing_edge, horizontal_line_start_y);
		let label_alignment = LabelAlignment::new(false, false, !selected_on_bottom);
		draw_line_with_length(line_start, line_end, transform, document_to_viewport, overlay_context, label_alignment);

		// Draw horizontal dashed line
		let dashed_line_start = DVec2::new(selected_facing_edge, dashed_horizontal_line_start_y);
		let dashed_line_end = DVec2::new(hovered_facing_edge, dashed_horizontal_line_start_y);
		draw_dashed_line(dashed_line_start, dashed_line_end, transform, overlay_context);
	}
}

/// Draws measurements when only one axis is involved and there is one crossing between selected and hovered bounds.
fn draw_single_axis_one_crossings(selected_bounds: Rect, hovered_bounds: Rect, transform: DAffine2, document_to_viewport: DAffine2, overlay_context: &mut OverlayContext) {
	let (selected_min, selected_max) = (selected_bounds.min(), selected_bounds.max());
	let (hovered_min, hovered_max) = (hovered_bounds.min(), hovered_bounds.max());

	let selected_center = selected_bounds.center();
	let hovered_center = hovered_bounds.center();

	let overlap_y = does_overlap_y(selected_bounds, hovered_bounds) || does_overlap_y(hovered_bounds, selected_bounds);
	let overlap_x = does_overlap_x(selected_bounds, hovered_bounds) || does_overlap_x(hovered_bounds, selected_bounds);

	if overlap_y {
		let selected_facing_edge = if hovered_max.y < selected_min.y { selected_min.y } else { selected_max.y };
		let hovered_facing_edge = if hovered_max.y < selected_min.y { hovered_max.y } else { hovered_min.y };
		let vertical_line_start = if selected_center.x < hovered_max.x && selected_center.x > hovered_min.x {
			selected_center.x
		} else {
			hovered_center.x
		};

		// Draw vertical solid line with length
		let line_start = DVec2::new(vertical_line_start, selected_facing_edge);
		let line_end = DVec2::new(vertical_line_start, hovered_facing_edge);
		let label_alignment = LabelAlignment::new(true, true, false);
		draw_line_with_length(line_start, line_end, transform, document_to_viewport, overlay_context, label_alignment);
	} else if overlap_x {
		let selected_facing_edge = if hovered_max.x < selected_min.x { selected_min.x } else { selected_max.x };
		let hovered_facing_edge = if hovered_max.x < selected_min.x { hovered_max.x } else { hovered_min.x };
		let horizontal_line_start_y = if selected_center.y < hovered_max.y && selected_center.y > hovered_min.y {
			selected_center.y
		} else {
			hovered_center.y
		};

		// Draw horizontal solid line with length
		let line_start = DVec2::new(selected_facing_edge, horizontal_line_start_y);
		let line_end = DVec2::new(hovered_facing_edge, horizontal_line_start_y);
		let label_alignment = LabelAlignment::new(false, false, true);
		draw_line_with_length(line_start, line_end, transform, document_to_viewport, overlay_context, label_alignment);
	}
}

/// Draws measurements for cases where lines cross on both X and Y axes, handling diagonal intersections.
fn draw_two_axis_one_one_crossing(selected_bounds: Rect, hovered_bounds: Rect, transform: DAffine2, document_to_viewport: DAffine2, overlay_context: &mut OverlayContext) {
	let (selected_min, selected_max) = (selected_bounds.min(), selected_bounds.max());
	let (hovered_min, hovered_max) = (hovered_bounds.min(), hovered_bounds.max());

	let mut top_y_bound = f64::min(selected_min.y, hovered_min.y);
	let mut bottom_y_bound = f64::max(selected_max.y, hovered_max.y);
	let mut top_x_bound = f64::max(selected_max.x, hovered_max.x);
	let mut bottom_x_bound = f64::min(selected_min.x, hovered_min.x);

	// Handle diagonal intersection cases by swapping bounds if necessary
	if (hovered_bounds.center().x > selected_bounds.center().x && hovered_bounds.center().y < selected_bounds.center().y)
		|| (hovered_bounds.center().x < selected_bounds.center().x && hovered_bounds.center().y > selected_bounds.center().y)
	{
		std::mem::swap(&mut top_y_bound, &mut bottom_y_bound);
		std::mem::swap(&mut top_x_bound, &mut bottom_x_bound);
	}

	// Draw horizontal solid lines with length
	let top_x_start = DVec2::new(f64::min(selected_max.x, hovered_max.x), top_y_bound);
	let top_x_end = DVec2::new(f64::max(selected_max.x, hovered_max.x), top_y_bound);
	let label_alignment = LabelAlignment::new(false, false, true);
	draw_line_with_length(top_x_start, top_x_end, transform, document_to_viewport, overlay_context, label_alignment);

	let bottom_x_start = DVec2::new(f64::min(selected_min.x, hovered_min.x), bottom_y_bound);
	let bottom_x_end = DVec2::new(f64::max(selected_min.x, hovered_min.x), bottom_y_bound);
	let label_alignment = LabelAlignment::new(false, false, false);
	draw_line_with_length(bottom_x_start, bottom_x_end, transform, document_to_viewport, overlay_context, label_alignment);

	// Draw vertical solid lines with length
	let top_y_start = DVec2::new(top_x_bound, f64::min(selected_min.y, hovered_min.y));
	let top_y_end = DVec2::new(top_x_bound, f64::max(selected_min.y, hovered_min.y));
	let label_alignment = LabelAlignment::new(true, false, false);
	draw_line_with_length(top_y_start, top_y_end, transform, document_to_viewport, overlay_context, label_alignment);

	let bottom_y_start = DVec2::new(bottom_x_bound, f64::min(selected_max.y, hovered_max.y));
	let bottom_y_end = DVec2::new(bottom_x_bound, f64::max(selected_max.y, hovered_max.y));
	let label_alignment = LabelAlignment::new(true, true, false);
	draw_line_with_length(bottom_y_start, bottom_y_end, transform, document_to_viewport, overlay_context, label_alignment);
}

/// Draws measurements for partial overlaps with two vertical or horizontal edge intersections.
fn draw_two_axis_one_one_two_zero_crossing(
	selected_bounds: Rect,
	hovered_bounds: Rect,
	transform: DAffine2,
	document_to_viewport: DAffine2,
	overlay_context: &mut OverlayContext,
	two_vertical_edge_intersect: bool,
) {
	let (selected_min, selected_max) = (selected_bounds.min(), selected_bounds.max());
	let (hovered_min, hovered_max) = (hovered_bounds.min(), hovered_bounds.max());

	if two_vertical_edge_intersect {
		let selected_bound_edge = if selected_bounds.center().y >= hovered_bounds.center().y {
			selected_max.y
		} else {
			selected_min.y
		};
		let hovered_bound_edge = if selected_bounds.center().y >= hovered_bounds.center().y { hovered_max.y } else { hovered_min.y };

		// Draw vertical solid lines with length
		let y_start_left = DVec2::new(hovered_min.x, f64::min(selected_bound_edge, hovered_bound_edge));
		let y_end_left = DVec2::new(hovered_min.x, f64::max(selected_bound_edge, hovered_bound_edge));
		let label_alignment = LabelAlignment::new(true, true, false);
		draw_line_with_length(y_start_left, y_end_left, transform, document_to_viewport, overlay_context, label_alignment);

		let y_start_right = DVec2::new(hovered_max.x, f64::min(selected_bound_edge, hovered_bound_edge));
		let y_end_right = DVec2::new(hovered_max.x, f64::max(selected_bound_edge, hovered_bound_edge));
		let label_alignment = LabelAlignment::new(true, false, false);
		draw_line_with_length(y_start_right, y_end_right, transform, document_to_viewport, overlay_context, label_alignment);

		// Draw horizontal solid lines with length
		let horizontal_line_y_bound = if selected_bounds.center().y >= hovered_bounds.center().y {
			f64::max(selected_bound_edge, hovered_bound_edge)
		} else {
			f64::min(selected_bound_edge, hovered_bound_edge)
		};

		let x_start_left = DVec2::new(hovered_min.x, horizontal_line_y_bound);
		let x_end_left = DVec2::new(selected_min.x, horizontal_line_y_bound);
		let label_alignment = LabelAlignment::new(false, false, false);
		draw_line_with_length(x_start_left, x_end_left, transform, document_to_viewport, overlay_context, label_alignment);

		let x_start_right = DVec2::new(hovered_max.x, horizontal_line_y_bound);
		let x_end_right = DVec2::new(selected_max.x, horizontal_line_y_bound);
		let label_alignment = LabelAlignment::new(false, false, false);
		draw_line_with_length(x_start_right, x_end_right, transform, document_to_viewport, overlay_context, label_alignment);
	} else {
		let selected_bound_edge = if selected_bounds.center().x >= hovered_bounds.center().x {
			selected_max.x
		} else {
			selected_min.x
		};
		let hovered_bound_edge = if selected_bounds.center().x >= hovered_bounds.center().x { hovered_max.x } else { hovered_min.x };

		// Determine the outermost X position for vertical lines
		let vertical_line_x = if selected_bounds.center().x >= hovered_bounds.center().x {
			f64::max(selected_bound_edge, hovered_bound_edge)
		} else {
			f64::min(selected_bound_edge, hovered_bound_edge)
		};

		// Draw vertical solid lines with length
		let y_start_up = DVec2::new(vertical_line_x, selected_min.y);
		let y_end_up = DVec2::new(vertical_line_x, hovered_min.y);
		let label_alignment = LabelAlignment::new(true, false, false);
		draw_line_with_length(y_start_up, y_end_up, transform, document_to_viewport, overlay_context, label_alignment);

		let y_start_down = DVec2::new(vertical_line_x, selected_max.y);
		let y_end_down = DVec2::new(vertical_line_x, hovered_max.y);
		let label_alignment = LabelAlignment::new(true, false, false);
		draw_line_with_length(y_start_down, y_end_down, transform, document_to_viewport, overlay_context, label_alignment);

		// Draw horizontal solid lines with length
		let horizontal_line_inner_x = if selected_bounds.center().x >= hovered_bounds.center().x {
			f64::min(selected_bound_edge, hovered_bound_edge)
		} else {
			f64::max(selected_bound_edge, hovered_bound_edge)
		};
		let x_start_up = DVec2::new(vertical_line_x, f64::min(selected_min.y, hovered_min.y));
		let x_end_up = DVec2::new(horizontal_line_inner_x, f64::min(selected_min.y, hovered_min.y));
		let label_alignment = LabelAlignment::new(false, false, true);
		draw_line_with_length(x_start_up, x_end_up, transform, document_to_viewport, overlay_context, label_alignment);

		let x_start_down = DVec2::new(vertical_line_x, f64::max(selected_max.y, hovered_max.y));
		let x_end_down = DVec2::new(horizontal_line_inner_x, f64::max(selected_max.y, hovered_max.y));
		let label_alignment = LabelAlignment::new(false, false, false);
		draw_line_with_length(x_start_down, x_end_down, transform, document_to_viewport, overlay_context, label_alignment);
	}
}

/// Draws measurements for cases with two vertical and two horizontal zero crossings.
fn draw_two_axis_two_zero_zero_two(selected_bounds: Rect, hovered_bounds: Rect, transform: DAffine2, document_to_viewport: DAffine2, overlay_context: &mut OverlayContext) {
	let (selected_min, selected_max) = (selected_bounds.min(), selected_bounds.max());
	let (hovered_min, hovered_max) = (hovered_bounds.min(), hovered_bounds.max());

	// Draw vertical solid lines with length
	let y_start_left_top = DVec2::new(f64::min(hovered_min.x, selected_min.x), f64::min(hovered_min.y, selected_min.y));
	let y_end_left_top = DVec2::new(f64::min(hovered_min.x, selected_min.x), f64::max(hovered_min.y, selected_min.y));
	let label_alignment = LabelAlignment::new(true, true, false);
	draw_line_with_length(y_start_left_top, y_end_left_top, transform, document_to_viewport, overlay_context, label_alignment);
	let label_alignment = LabelAlignment::new(true, true, false);
	draw_line_with_length(y_start_left_top, y_end_left_top, transform, document_to_viewport, overlay_context, label_alignment);

	let y_start_left_bottom = DVec2::new(f64::min(hovered_min.x, selected_min.x), f64::min(hovered_max.y, selected_max.y));
	let y_end_left_bottom = DVec2::new(f64::min(hovered_min.x, selected_min.x), f64::max(hovered_max.y, selected_max.y));
	let label_alignment = LabelAlignment::new(true, true, false);
	draw_line_with_length(y_start_left_bottom, y_end_left_bottom, transform, document_to_viewport, overlay_context, label_alignment);

	let y_start_right_top = DVec2::new(f64::max(hovered_max.x, selected_max.x), f64::min(hovered_min.y, selected_min.y));
	let y_end_right_top = DVec2::new(f64::max(hovered_max.x, selected_max.x), f64::max(hovered_min.y, selected_min.y));
	let label_alignment = LabelAlignment::new(true, false, false);
	draw_line_with_length(y_start_right_top, y_end_right_top, transform, document_to_viewport, overlay_context, label_alignment);

	let y_start_right_bottom = DVec2::new(f64::max(hovered_max.x, selected_max.x), f64::min(hovered_max.y, selected_max.y));
	let y_end_right_bottom = DVec2::new(f64::max(hovered_max.x, selected_max.x), f64::max(hovered_max.y, selected_max.y));
	let label_alignment = LabelAlignment::new(true, false, false);
	draw_line_with_length(y_start_right_bottom, y_end_right_bottom, transform, document_to_viewport, overlay_context, label_alignment);

	// Draw horizontal solid lines with length
	let x_start_left_top = DVec2::new(f64::min(hovered_min.x, selected_min.x), f64::min(hovered_min.y, selected_min.y));
	let x_end_left_top = DVec2::new(f64::max(hovered_min.x, selected_min.x), f64::min(hovered_min.y, selected_min.y));
	let label_alignment = LabelAlignment::new(false, false, true);
	draw_line_with_length(x_start_left_top, x_end_left_top, transform, document_to_viewport, overlay_context, label_alignment);

	let x_start_right_top = DVec2::new(f64::min(hovered_max.x, selected_max.x), f64::min(hovered_min.y, selected_min.y));
	let x_end_right_top = DVec2::new(f64::max(hovered_max.x, selected_max.x), f64::min(hovered_min.y, selected_min.y));
	let label_alignment = LabelAlignment::new(false, false, true);
	draw_line_with_length(x_start_right_top, x_end_right_top, transform, document_to_viewport, overlay_context, label_alignment);

	let x_start_left_bottom = DVec2::new(f64::min(hovered_min.x, selected_min.x), f64::max(hovered_max.y, selected_max.y));
	let x_end_left_bottom = DVec2::new(f64::max(hovered_min.x, selected_min.x), f64::max(hovered_max.y, selected_max.y));
	let label_alignment = LabelAlignment::new(false, false, false);
	draw_line_with_length(x_start_left_bottom, x_end_left_bottom, transform, document_to_viewport, overlay_context, label_alignment);

	let x_start_right_bottom = DVec2::new(f64::min(hovered_max.x, selected_max.x), f64::max(hovered_max.y, selected_max.y));
	let x_end_right_bottom = DVec2::new(f64::max(hovered_max.x, selected_max.x), f64::max(hovered_max.y, selected_max.y));
	let label_alignment = LabelAlignment::new(false, false, false);
	draw_line_with_length(x_start_right_bottom, x_end_right_bottom, transform, document_to_viewport, overlay_context, label_alignment);
}

/// Draws measurements where selected and hovered bounds have two vertical edges crossing each other.
fn draw_two_axis_two_zero_two_zero(selected_bounds: Rect, hovered_bounds: Rect, transform: DAffine2, document_to_viewport: DAffine2, overlay_context: &mut OverlayContext) {
	let (selected_min, selected_max) = (selected_bounds.min(), selected_bounds.max());
	let (hovered_min, hovered_max) = (hovered_bounds.min(), hovered_bounds.max());

	// Draw horizontal solid lines with length
	let x_start_left = DVec2::new(f64::max(hovered_min.x, selected_min.x), selected_bounds.center().y);
	let x_end_left = DVec2::new(f64::min(hovered_min.x, selected_min.x), selected_bounds.center().y);
	let label_alignment = LabelAlignment::new(false, false, true);
	draw_line_with_length(x_start_left, x_end_left, transform, document_to_viewport, overlay_context, label_alignment);

	let x_start_right = DVec2::new(f64::min(hovered_max.x, selected_max.x), selected_bounds.center().y);
	let x_end_right = DVec2::new(f64::max(hovered_max.x, selected_max.x), selected_bounds.center().y);
	let label_alignment = LabelAlignment::new(false, false, true);
	draw_line_with_length(x_start_right, x_end_right, transform, document_to_viewport, overlay_context, label_alignment);

	// Draw vertical solid lines with length
	let y_start_top = DVec2::new(selected_bounds.center().x, f64::max(hovered_min.y, selected_min.y));
	let y_end_top = DVec2::new(selected_bounds.center().x, f64::min(hovered_min.y, selected_min.y));
	let label_alignment = LabelAlignment::new(true, false, false);
	draw_line_with_length(y_start_top, y_end_top, transform, document_to_viewport, overlay_context, label_alignment);

	let y_start_bottom = DVec2::new(selected_bounds.center().x, f64::min(hovered_max.y, selected_max.y));
	let y_end_bottom = DVec2::new(selected_bounds.center().x, f64::max(hovered_max.y, selected_max.y));
	let label_alignment = LabelAlignment::new(true, false, false);
	draw_line_with_length(y_start_bottom, y_end_bottom, transform, document_to_viewport, overlay_context, label_alignment);
}

/// Handles overlapping scenarios involving two axes between selected and hovered bounds.
fn handle_two_axis_overlap(selected_bounds: Rect, hovered_bounds: Rect, transform: DAffine2, document_to_viewport: DAffine2, overlay_context: &mut OverlayContext) {
	let (selected_min, selected_max) = (selected_bounds.min(), selected_bounds.max());
	let (hovered_min, hovered_max) = (hovered_bounds.min(), hovered_bounds.max());

	// Calculate edge crossings on the X-axis
	let selected_x_crosses = (selected_min.y >= hovered_min.y && selected_min.y <= hovered_max.y) as u8 + (selected_max.y >= hovered_min.y && selected_max.y <= hovered_max.y) as u8;
	let hovered_x_crosses = (hovered_min.y >= selected_min.y && hovered_min.y <= selected_max.y) as u8 + (hovered_max.y >= selected_min.y && hovered_max.y <= selected_max.y) as u8;

	// Calculate edge crossings on the Y-axis
	let selected_y_crosses = (selected_min.x >= hovered_min.x && selected_min.x <= hovered_max.x) as u8 + (selected_max.x >= hovered_min.x && selected_max.x <= hovered_max.x) as u8;
	let hovered_y_crosses = (hovered_min.x >= selected_min.x && hovered_min.x <= selected_max.x) as u8 + (hovered_max.x >= selected_min.x && hovered_max.x <= selected_max.x) as u8;

	// Determine the overlap case based on edge crossings
	match ((selected_x_crosses, hovered_x_crosses), (selected_y_crosses, hovered_y_crosses)) {
		((1, 1), (1, 1)) => draw_two_axis_one_one_crossing(selected_bounds, hovered_bounds, transform, document_to_viewport, overlay_context),
		((1, 1), (2, 0)) => draw_two_axis_one_one_two_zero_crossing(selected_bounds, hovered_bounds, transform, document_to_viewport, overlay_context, true),
		((1, 1), (0, 2)) => draw_two_axis_one_one_two_zero_crossing(hovered_bounds, selected_bounds, transform, document_to_viewport, overlay_context, true),
		((2, 0), (1, 1)) => draw_two_axis_one_one_two_zero_crossing(selected_bounds, hovered_bounds, transform, document_to_viewport, overlay_context, false),
		((0, 2), (1, 1)) => draw_two_axis_one_one_two_zero_crossing(hovered_bounds, selected_bounds, transform, document_to_viewport, overlay_context, false),
		((2, 0), (0, 2)) | ((0, 2), (2, 0)) => draw_two_axis_two_zero_zero_two(selected_bounds, hovered_bounds, transform, document_to_viewport, overlay_context),
		((2, 0), (2, 0)) | ((0, 2), (0, 2)) => draw_two_axis_two_zero_two_zero(selected_bounds, hovered_bounds, transform, document_to_viewport, overlay_context),
		_ => (),
	}
}

/// Overlays measurement lines between selected and hovered bounds based on their spatial relationships.
pub fn overlay(selected_bounds: Rect, hovered_bounds: Rect, transform: DAffine2, document_to_viewport: DAffine2, overlay_context: &mut OverlayContext) {
	draw_dashed_rect_outline(selected_bounds, transform, overlay_context);
	draw_dashed_rect_outline(hovered_bounds, transform, overlay_context);
	let (selected_min, selected_max) = (selected_bounds.min(), selected_bounds.max());
	let (hovered_min, hovered_max) = (hovered_bounds.min(), hovered_bounds.max());

	// Determine axis overlaps
	let overlap_y = does_overlap_y(selected_bounds, hovered_bounds) || does_overlap_y(hovered_bounds, selected_bounds);
	let overlap_x = does_overlap_x(selected_bounds, hovered_bounds) || does_overlap_x(hovered_bounds, selected_bounds);
	let overlap_axes = match (overlap_x, overlap_y) {
		(true, true) => 2,
		(true, false) | (false, true) => 1,
		_ => 0,
	};

	// Determine centerline crossings
	let center_x_intersects =
		(selected_bounds.center().y >= hovered_min.y && selected_bounds.center().y <= hovered_max.y) || (hovered_bounds.center().y >= selected_min.y && hovered_bounds.center().y <= selected_max.y);
	let center_y_intersects =
		(selected_bounds.center().x >= hovered_min.x && selected_bounds.center().x <= hovered_max.x) || (hovered_bounds.center().x >= selected_min.x && hovered_bounds.center().x <= selected_max.x);
	let centerline_crosses = match (center_x_intersects, center_y_intersects) {
		(true, true) => 2,
		(true, false) | (false, true) => 1,
		_ => 0,
	};

	// Handle each overlap case
	match (overlap_axes, centerline_crosses) {
		(0, _) => draw_zero_axis_crossings(selected_bounds, hovered_bounds, transform, document_to_viewport, overlay_context),
		(1, 0) => draw_single_axis_zero_crossings(selected_bounds, hovered_bounds, transform, document_to_viewport, overlay_context),
		(1, 1) | (1, 2) => draw_single_axis_one_crossings(selected_bounds, hovered_bounds, transform, document_to_viewport, overlay_context),
		(2, _) => handle_two_axis_overlap(selected_bounds, hovered_bounds, transform, document_to_viewport, overlay_context),
		_ => (), // Fallback case, should not typically happen
	}
}

struct LabelAlignment {
	is_vertical_line: bool,
	text_on_left: bool,
	text_on_top: bool,
}

impl LabelAlignment {
	fn new(is_vertical_line: bool, text_on_left: bool, text_on_top: bool) -> Self {
		Self {
			is_vertical_line,
			text_on_left,
			text_on_top,
		}
	}
}