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}