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 //! 35 use crate::{compute::grid::OriginZeroLine, geometry::Line}; 36 use 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)] 41 pub(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 50 impl TrackCounts { 51 /// Create a TrackCounts instance from raw track count numbers from_raw(negative_implicit: u16, explicit: u16, positive_implicit: u16) -> Self52 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 len(&self) -> usize57 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 implicit_start_line(&self) -> OriginZeroLine62 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 implicit_end_line(&self) -> OriginZeroLine67 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)] 74 impl TrackCounts { 75 /// Converts a grid line in OriginZero coordinates into the track immediately 76 /// following that grid line as an index into the CellOccupancyMatrix. oz_line_to_next_track(&self, index: OriginZeroLine) -> i1677 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 oz_line_range_to_track_range(&self, input: Line<OriginZeroLine>) -> Range<i16>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. track_to_prev_oz_line(&self, index: u16) -> OriginZeroLine91 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 track_range_to_oz_line_range(&self, input: Range<i16>) -> Line<OriginZeroLine>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 } 103