taffy/compute/grid/types/grid_track_counts.rs
1//! Contains TrackCounts used to keep track of the number of tracks in the explicit and implicit grids.
2//! Also contains coordinate conversion functions which depend on those counts
3//!
4//! Taffy uses two coordinate systems to refer to grid lines (the gaps/gutters between rows/columns):
5//!
6//! "CSS Grid Line" coordinates are those used in grid-row/grid-column in the CSS grid spec:
7//! - 0 is not a valid index
8//! - The line at left hand (or top) edge of the explicit grid is line 1
9//! (and counts up from there)
10//! - The line at the right hand (or bottom) edge of the explicit grid in -1
11//! (and counts down from there)
12//!
13//! "OriginZero" coordinates are a normalized form:
14//! - The line at left hand (or top) edge of the explicit grid is line 0
15//! - The next line to the right (or down) is 1, and so on
16//! - The next line to the left (or up) is -1, and so on
17//!
18//! Taffy also uses two coordinate systems to refer to grid tracks (rows/columns):
19//!
20//! Both of these systems represent the entire implicit grid, not just the explicit grid.
21//!
22//! "CellOccupancyMatrix track indices":
23//! - These are indexes into the CellOccupancyMatrix
24//! - The CellOccupancyMatrix stores only tracks
25//! - 0 is the leftmost track of the implicit grid, and indexes count up there
26//!
27//! "GridTrackVec track indices":
28//! - The GridTrackVecs store both lines and tracks, so:
29//! - even indices (0, 2, 4, etc) represent lines
30//! - odd indices (1, 3, 5, etc) represent tracks
31//! - These is always an odd number of
32//! - Index 1 is the leftmost track of the implicit grid. Index 3 is the second leftmost track, etc.
33//! - Index 0 is the leftmost grid line. Index 2 is the second leftmost line, etc.
34//!
35use crate::{compute::grid::OriginZeroLine, geometry::Line};
36use core::ops::Range;
37
38/// Stores the number of tracks in a given dimension.
39/// Stores separately the number of tracks in the implicit and explicit grids
40#[derive(Clone, Copy, Debug, PartialEq, Default)]
41pub(crate) struct TrackCounts {
42 /// The number of track in the implicit grid before the explicit grid
43 pub negative_implicit: u16,
44 /// The number of tracks in the explicit grid
45 pub explicit: u16,
46 /// The number of tracks in the implicit grid after the explicit grid
47 pub positive_implicit: u16,
48}
49
50impl TrackCounts {
51 /// Create a TrackCounts instance from raw track count numbers
52 pub fn from_raw(negative_implicit: u16, explicit: u16, positive_implicit: u16) -> Self {
53 Self { negative_implicit, explicit, positive_implicit }
54 }
55
56 /// Count the total number of tracks in the axis
57 pub fn len(&self) -> usize {
58 (self.negative_implicit + self.explicit + self.positive_implicit) as usize
59 }
60
61 /// The OriginZeroLine representing the start of the implicit grid
62 pub fn implicit_start_line(&self) -> OriginZeroLine {
63 OriginZeroLine(-(self.negative_implicit as i16))
64 }
65
66 /// The OriginZeroLine representing the end of the implicit grid
67 pub fn implicit_end_line(&self) -> OriginZeroLine {
68 OriginZeroLine((self.explicit + self.positive_implicit) as i16)
69 }
70}
71
72/// Conversion functions between OriginZero coordinates and CellOccupancyMatrix track indexes
73#[allow(dead_code)]
74impl TrackCounts {
75 /// Converts a grid line in OriginZero coordinates into the track immediately
76 /// following that grid line as an index into the CellOccupancyMatrix.
77 pub fn oz_line_to_next_track(&self, index: OriginZeroLine) -> i16 {
78 index.0 + (self.negative_implicit as i16)
79 }
80
81 /// Converts start and end grid lines in OriginZero coordinates into a range of tracks
82 /// as indexes into the CellOccupancyMatrix
83 pub fn oz_line_range_to_track_range(&self, input: Line<OriginZeroLine>) -> Range<i16> {
84 let start = self.oz_line_to_next_track(input.start);
85 let end = self.oz_line_to_next_track(input.end); // Don't subtract 1 as output range is exclusive
86 start..end
87 }
88
89 /// Converts a track as an index into the CellOccupancyMatrix into the grid line immediately
90 /// preceding that track in OriginZero coordinates.
91 pub fn track_to_prev_oz_line(&self, index: u16) -> OriginZeroLine {
92 OriginZeroLine((index as i16) - (self.negative_implicit as i16))
93 }
94
95 /// Converts a range of tracks as indexes into the CellOccupancyMatrix into
96 /// start and end grid lines in OriginZero coordinates
97 pub fn track_range_to_oz_line_range(&self, input: Range<i16>) -> Line<OriginZeroLine> {
98 let start = self.track_to_prev_oz_line(input.start as u16);
99 let end = self.track_to_prev_oz_line(input.end as u16); // Don't add 1 as input range is exclusive
100 Line { start, end }
101 }
102}