Grid/refactor coordinate handling (#301)
* Use style helpers for creating GridPlacement::Line in gentests
* Introduce newtype system for grid line coordinate handling
* Add test for correct grid line coordinate handling
* Use i16 rather than NonZeroI16 as the backing storage for GridLine, and convert to Auto internally if zero is specified
* Update src/style/grid.rs
Co-authored-by: Andreas Weibye <13300393+Weibye@users.noreply.github.com>
* Update src/style/grid.rs
Co-authored-by: Andreas Weibye <13300393+Weibye@users.noreply.github.com>
* Fix typo
* Add unsigned_abs method to OriginZeroLine
* Improve estimate of grid size
* Add span method to Line<OriginZeroLine>
* Fix auto placement in negative tracks
* Update changelog with new GridLine type
Co-authored-by: Andreas Weibye <13300393+Weibye@users.noreply.github.com>
Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
859cc921b3adb8e3b184e6fc0cf0c40b6c5a625b · ruwaq Nico Burns · 2023-01-02T17:20:53Z (3 wata ñawpaq) · tayta 30f836428 · kay commitpi sach'ata qhaway
Semántico sayk'uy · 115
benches/generated/grid_absolute_column_end.rs
ukhunpi t'ikrakurqan fn compute pub
benches/generated/grid_absolute_column_start.rs
ukhunpi t'ikrakurqan fn compute pub
benches/generated/grid_absolute_row_end.rs
ukhunpi t'ikrakurqan fn compute pub
benches/generated/grid_absolute_row_start.rs
ukhunpi t'ikrakurqan fn compute pub
benches/generated/grid_align_items_sized_center.rs
ukhunpi t'ikrakurqan fn compute pub
benches/generated/grid_align_items_sized_end.rs
ukhunpi t'ikrakurqan fn compute pub
benches/generated/grid_align_items_sized_start.rs
ukhunpi t'ikrakurqan fn compute pub
benches/generated/grid_align_items_sized_stretch.rs
ukhunpi t'ikrakurqan fn compute pub
benches/generated/grid_justify_items_sized_center.rs
ukhunpi t'ikrakurqan fn compute pub
benches/generated/grid_justify_items_sized_end.rs
ukhunpi t'ikrakurqan fn compute pub
benches/generated/grid_justify_items_sized_start.rs
ukhunpi t'ikrakurqan fn compute pub
benches/generated/grid_justify_items_sized_stretch.rs
ukhunpi t'ikrakurqan fn compute pub
benches/generated/grid_out_of_order_items.rs
ukhunpi t'ikrakurqan fn compute pub
benches/generated/grid_placement_auto_negative.rs
benches/generated/grid_placement_definite_in_secondary_axis_with_fully_definite_negative.rs
scripts/gentest/src/main.rs
src/compute/grid/implicit_grid.rs
src/compute/grid/mod.rs
ukhunpi t'ikrakurqan fn compute pub
src/compute/grid/placement.rs
src/compute/grid/track_sizing.rs
src/compute/grid/types/cell_occupancy.rs
src/compute/grid/types/coordinates.rs
src/compute/grid/types/grid_item.rs
src/compute/grid/types/grid_track_counts.rs
src/compute/grid/types/mod.rs
src/compute/grid/util/coordinates.rs
src/compute/grid/util/mod.rs
src/compute/grid/util/test_helpers.rs
tests/generated/grid_absolute_column_end.rs
tests/generated/grid_absolute_column_start.rs
tests/generated/grid_absolute_row_end.rs
tests/generated/grid_absolute_row_start.rs
tests/generated/grid_align_items_sized_center.rs
tests/generated/grid_align_items_sized_end.rs
tests/generated/grid_align_items_sized_start.rs
tests/generated/grid_align_items_sized_stretch.rs
tests/generated/grid_justify_items_sized_center.rs
tests/generated/grid_justify_items_sized_end.rs
tests/generated/grid_justify_items_sized_start.rs
tests/generated/grid_justify_items_sized_stretch.rs
tests/generated/grid_out_of_order_items.rs
tests/generated/grid_placement_auto_negative.rs
tests/generated/grid_placement_definite_in_secondary_axis_with_fully_definite_negative.rs
51 qillqakuna · +807 −617
diff --git a/RELEASES.md b/RELEASES.md
index c3e92e967..af9b1a56a 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -6,12 +6,13 @@
- `experimental_grid` feature named to just `grid`
- `grid` feature enabled by default
+- `GridPlacement::Line` now stores a `GridLine` newtype wrapper around an `i16` rather than a raw `i16`. If you are using the style helpers then this change will not affect you.
+- *BREAKING:* `Position` is now renamed to `Inset` and is now in line with [CSS inset specs](https://developer.mozilla.org/en-US/docs/Web/CSS/inset)
+- *BREAKING:* `PositionType` is now renamed to `Position` and is now in line with [CSS position specs](https://developer.mozilla.org/en-US/docs/Web/CSS/position)
### Fixes
- Flexbox nodes sized under a min-content constraint now size correctly (#291)
-- *BREAKING:* `Position` is now renamed to `Inset` and is now in line with [CSS inset specs](https://developer.mozilla.org/en-US/docs/Web/CSS/inset)
-- *BREAKING:* `PositionType` is now renamed to `Position` and is now in line with [CSS position specs](https://developer.mozilla.org/en-US/docs/Web/CSS/position)
### Removed
diff --git a/benches/generated/grid_absolute_column_end.rs b/benches/generated/grid_absolute_column_end.rs
index 06ef955eb..60cfa519e 100644
--- a/benches/generated/grid_absolute_column_end.rs
+++ b/benches/generated/grid_absolute_column_end.rs
@@ -5,10 +5,7 @@ pub fn compute() {
let node0 = taffy
.new_leaf(taffy::style::Style {
position: taffy::style::Position::Absolute,
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Auto,
- end: taffy::style::GridPlacement::Line(1i16),
- },
+ grid_column: taffy::geometry::Line { start: taffy::style::GridPlacement::Auto, end: line(1i16) },
inset: taffy::geometry::Rect {
left: taffy::style::LengthPercentageAuto::Points(4f32),
right: taffy::style::LengthPercentageAuto::Points(3f32),
diff --git a/benches/generated/grid_absolute_column_start.rs b/benches/generated/grid_absolute_column_start.rs
index e81125301..11362c184 100644
--- a/benches/generated/grid_absolute_column_start.rs
+++ b/benches/generated/grid_absolute_column_start.rs
@@ -5,10 +5,7 @@ pub fn compute() {
let node0 = taffy
.new_leaf(taffy::style::Style {
position: taffy::style::Position::Absolute,
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
inset: taffy::geometry::Rect {
left: taffy::style::LengthPercentageAuto::Points(4f32),
right: taffy::style::LengthPercentageAuto::Points(3f32),
diff --git a/benches/generated/grid_absolute_row_end.rs b/benches/generated/grid_absolute_row_end.rs
index 571cebfb5..2526a81fa 100644
--- a/benches/generated/grid_absolute_row_end.rs
+++ b/benches/generated/grid_absolute_row_end.rs
@@ -5,10 +5,7 @@ pub fn compute() {
let node0 = taffy
.new_leaf(taffy::style::Style {
position: taffy::style::Position::Absolute,
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Auto,
- end: taffy::style::GridPlacement::Line(1i16),
- },
+ grid_row: taffy::geometry::Line { start: taffy::style::GridPlacement::Auto, end: line(1i16) },
inset: taffy::geometry::Rect {
left: taffy::style::LengthPercentageAuto::Points(4f32),
right: taffy::style::LengthPercentageAuto::Points(3f32),
diff --git a/benches/generated/grid_absolute_row_start.rs b/benches/generated/grid_absolute_row_start.rs
index c3940bbef..66975aef0 100644
--- a/benches/generated/grid_absolute_row_start.rs
+++ b/benches/generated/grid_absolute_row_start.rs
@@ -5,10 +5,7 @@ pub fn compute() {
let node0 = taffy
.new_leaf(taffy::style::Style {
position: taffy::style::Position::Absolute,
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
inset: taffy::geometry::Rect {
left: taffy::style::LengthPercentageAuto::Points(4f32),
right: taffy::style::LengthPercentageAuto::Points(3f32),
diff --git a/benches/generated/grid_align_items_sized_center.rs b/benches/generated/grid_align_items_sized_center.rs
index 67f4c5d78..d7cb9e00f 100644
--- a/benches/generated/grid_align_items_sized_center.rs
+++ b/benches/generated/grid_align_items_sized_center.rs
@@ -4,14 +4,8 @@ pub fn compute() {
let mut taffy = taffy::Taffy::new();
let node0 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(20f32),
height: taffy::style::Dimension::Points(20f32),
@@ -21,14 +15,8 @@ pub fn compute() {
.unwrap();
let node1 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(60f32),
height: taffy::style::Dimension::Points(60f32),
diff --git a/benches/generated/grid_align_items_sized_end.rs b/benches/generated/grid_align_items_sized_end.rs
index 6ec0a4abc..200df8105 100644
--- a/benches/generated/grid_align_items_sized_end.rs
+++ b/benches/generated/grid_align_items_sized_end.rs
@@ -4,14 +4,8 @@ pub fn compute() {
let mut taffy = taffy::Taffy::new();
let node0 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(20f32),
height: taffy::style::Dimension::Points(20f32),
@@ -21,14 +15,8 @@ pub fn compute() {
.unwrap();
let node1 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(60f32),
height: taffy::style::Dimension::Points(60f32),
diff --git a/benches/generated/grid_align_items_sized_start.rs b/benches/generated/grid_align_items_sized_start.rs
index 16d9f0588..b1882f104 100644
--- a/benches/generated/grid_align_items_sized_start.rs
+++ b/benches/generated/grid_align_items_sized_start.rs
@@ -4,14 +4,8 @@ pub fn compute() {
let mut taffy = taffy::Taffy::new();
let node0 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(20f32),
height: taffy::style::Dimension::Points(20f32),
@@ -21,14 +15,8 @@ pub fn compute() {
.unwrap();
let node1 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(60f32),
height: taffy::style::Dimension::Points(60f32),
diff --git a/benches/generated/grid_align_items_sized_stretch.rs b/benches/generated/grid_align_items_sized_stretch.rs
index 349562e6a..96512291c 100644
--- a/benches/generated/grid_align_items_sized_stretch.rs
+++ b/benches/generated/grid_align_items_sized_stretch.rs
@@ -4,14 +4,8 @@ pub fn compute() {
let mut taffy = taffy::Taffy::new();
let node0 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(20f32),
height: taffy::style::Dimension::Points(20f32),
@@ -21,14 +15,8 @@ pub fn compute() {
.unwrap();
let node1 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(60f32),
height: taffy::style::Dimension::Points(60f32),
diff --git a/benches/generated/grid_justify_items_sized_center.rs b/benches/generated/grid_justify_items_sized_center.rs
index 1fa28e5f6..c02604a7b 100644
--- a/benches/generated/grid_justify_items_sized_center.rs
+++ b/benches/generated/grid_justify_items_sized_center.rs
@@ -4,14 +4,8 @@ pub fn compute() {
let mut taffy = taffy::Taffy::new();
let node0 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(20f32),
height: taffy::style::Dimension::Points(20f32),
@@ -21,14 +15,8 @@ pub fn compute() {
.unwrap();
let node1 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(60f32),
height: taffy::style::Dimension::Points(60f32),
diff --git a/benches/generated/grid_justify_items_sized_end.rs b/benches/generated/grid_justify_items_sized_end.rs
index 836b4ca2b..47844d4e9 100644
--- a/benches/generated/grid_justify_items_sized_end.rs
+++ b/benches/generated/grid_justify_items_sized_end.rs
@@ -4,14 +4,8 @@ pub fn compute() {
let mut taffy = taffy::Taffy::new();
let node0 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(20f32),
height: taffy::style::Dimension::Points(20f32),
@@ -21,14 +15,8 @@ pub fn compute() {
.unwrap();
let node1 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(60f32),
height: taffy::style::Dimension::Points(60f32),
diff --git a/benches/generated/grid_justify_items_sized_start.rs b/benches/generated/grid_justify_items_sized_start.rs
index 4b6ee18f5..5cd3ed913 100644
--- a/benches/generated/grid_justify_items_sized_start.rs
+++ b/benches/generated/grid_justify_items_sized_start.rs
@@ -4,14 +4,8 @@ pub fn compute() {
let mut taffy = taffy::Taffy::new();
let node0 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(20f32),
height: taffy::style::Dimension::Points(20f32),
@@ -21,14 +15,8 @@ pub fn compute() {
.unwrap();
let node1 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(60f32),
height: taffy::style::Dimension::Points(60f32),
diff --git a/benches/generated/grid_justify_items_sized_stretch.rs b/benches/generated/grid_justify_items_sized_stretch.rs
index 6a8b3feaa..c936740f7 100644
--- a/benches/generated/grid_justify_items_sized_stretch.rs
+++ b/benches/generated/grid_justify_items_sized_stretch.rs
@@ -4,14 +4,8 @@ pub fn compute() {
let mut taffy = taffy::Taffy::new();
let node0 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(20f32),
height: taffy::style::Dimension::Points(20f32),
@@ -21,14 +15,8 @@ pub fn compute() {
.unwrap();
let node1 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(60f32),
height: taffy::style::Dimension::Points(60f32),
diff --git a/benches/generated/grid_out_of_order_items.rs b/benches/generated/grid_out_of_order_items.rs
index cbb487bfc..b6bc62472 100644
--- a/benches/generated/grid_out_of_order_items.rs
+++ b/benches/generated/grid_out_of_order_items.rs
@@ -6,10 +6,7 @@ pub fn compute() {
let node1 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
let node2 = taffy
.new_leaf(taffy::style::Style {
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(35f32),
height: taffy::style::Dimension::Points(35f32),
@@ -21,14 +18,8 @@ pub fn compute() {
let node4 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
let node5 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(20f32),
height: taffy::style::Dimension::Points(20f32),
@@ -39,10 +30,7 @@ pub fn compute() {
let node6 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
let node7 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(10f32),
height: taffy::style::Dimension::Points(10f32),
diff --git a/benches/generated/grid_placement_auto_negative.rs b/benches/generated/grid_placement_auto_negative.rs
new file mode 100644
index 000000000..1898ac983
--- /dev/null
+++ b/benches/generated/grid_placement_auto_negative.rs
@@ -0,0 +1,35 @@
+pub fn compute() {
+ #[allow(unused_imports)]
+ use taffy::prelude::*;
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(-5i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node1 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node2 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(2i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Grid,
+ grid_template_rows: vec![points(40f32), points(40f32)],
+ grid_template_columns: vec![points(40f32), points(40f32)],
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Points(120f32),
+ height: taffy::style::Dimension::Points(120f32),
+ },
+ ..Default::default()
+ },
+ &[node0, node1, node2],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_placement_definite_in_secondary_axis_with_fully_definite_negative.rs b/benches/generated/grid_placement_definite_in_secondary_axis_with_fully_definite_negative.rs
new file mode 100644
index 000000000..840997a9b
--- /dev/null
+++ b/benches/generated/grid_placement_definite_in_secondary_axis_with_fully_definite_negative.rs
@@ -0,0 +1,41 @@
+pub fn compute() {
+ #[allow(unused_imports)]
+ use taffy::prelude::*;
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(2i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node1 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(2i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(-4i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node2 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node3 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Grid,
+ grid_template_rows: vec![points(40f32), points(40f32)],
+ grid_template_columns: vec![points(40f32), points(40f32)],
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Points(120f32),
+ height: taffy::style::Dimension::Points(120f32),
+ },
+ ..Default::default()
+ },
+ &[node0, node1, node2, node3],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/mod.rs b/benches/generated/mod.rs
index ea7234c7d..073f120a7 100644
--- a/benches/generated/mod.rs
+++ b/benches/generated/mod.rs
@@ -413,6 +413,10 @@ mod grid_percent_width_and_margin;
#[cfg(feature = "grid")]
mod grid_percent_width_and_padding;
#[cfg(feature = "grid")]
+mod grid_placement_auto_negative;
+#[cfg(feature = "grid")]
+mod grid_placement_definite_in_secondary_axis_with_fully_definite_negative;
+#[cfg(feature = "grid")]
mod grid_relayout_vertical_text;
#[cfg(feature = "grid")]
mod grid_size_child_fixed_tracks;
@@ -923,6 +927,10 @@ fn benchmark(c: &mut Criterion) {
#[cfg(feature = "grid")]
grid_percent_width_and_padding::compute();
#[cfg(feature = "grid")]
+ grid_placement_auto_negative::compute();
+ #[cfg(feature = "grid")]
+ grid_placement_definite_in_secondary_axis_with_fully_definite_negative::compute();
+ #[cfg(feature = "grid")]
grid_relayout_vertical_text::compute();
#[cfg(feature = "grid")]
grid_size_child_fixed_tracks::compute();
diff --git a/scripts/gentest/src/main.rs b/scripts/gentest/src/main.rs
index 83c847f1f..7d43e7b06 100644
--- a/scripts/gentest/src/main.rs
+++ b/scripts/gentest/src/main.rs
@@ -714,7 +714,7 @@ fn generate_grid_position(grid_position: &serde_json::Map<String, Value>) -> Tok
}
"line" => {
let value = value() as i16;
- quote!(taffy::style::GridPlacement::Line(#value))
+ quote!(line(#value))
}
_ => unreachable!(),
},
diff --git a/src/compute/grid/implicit_grid.rs b/src/compute/grid/implicit_grid.rs
index 2319b0caf..25b0ea350 100644
--- a/src/compute/grid/implicit_grid.rs
+++ b/src/compute/grid/implicit_grid.rs
@@ -1,11 +1,11 @@
//! This module is not required for spec compliance, but is used as a performance optimisation
//! to reduce the number of allocations required when creating a grid.
use crate::geometry::Line;
-use crate::style::{GridPlacement, Style};
+use crate::style::{GenericGridPlacement, GridPlacement, Style};
use core::cmp::{max, min};
use super::types::TrackCounts;
-use super::util::css_grid_line_into_origin_zero_coords;
+use super::OriginZeroLine;
/// Estimate the number of rows and columns in the grid
/// This is used as a performance optimisation to pre-size vectors and reduce allocations. It also forms a necessary step
@@ -28,12 +28,12 @@ pub(crate) fn compute_grid_size_estimate<'a>(
// Compute *track* count estimates for each axis from:
// - The explicit track counts
// - The origin-zero coordinate min and max grid line variables
- let negative_implicit_inline_tracks = col_min.unsigned_abs();
+ let negative_implicit_inline_tracks = col_min.implied_negative_implicit_tracks();
let explicit_inline_tracks = explicit_col_count;
- let mut positive_implicit_inline_tracks = max(explicit_col_count, col_max.unsigned_abs()) - explicit_col_count;
- let negative_implicit_block_tracks = row_min.unsigned_abs();
+ let mut positive_implicit_inline_tracks = col_max.implied_positive_implicit_tracks(explicit_col_count);
+ let negative_implicit_block_tracks = row_min.implied_negative_implicit_tracks();
let explicit_block_tracks = explicit_row_count;
- let mut positive_implicit_block_tracks = max(explicit_row_count, row_max.unsigned_abs()) - explicit_row_count;
+ let mut positive_implicit_block_tracks = row_max.implied_positive_implicit_tracks(explicit_row_count);
// In each axis, adjust positive track estimate if any items have a span that does not fit within
// the total number of tracks in the estimate
@@ -64,8 +64,9 @@ fn get_known_child_positions<'a>(
children_iter: impl Iterator<Item = &'a Style>,
explicit_col_count: u16,
explicit_row_count: u16,
-) -> (i16, i16, u16, i16, i16, u16) {
- let (mut col_min, mut col_max, mut col_max_span, mut row_min, mut row_max, mut row_max_span) = (0, 0, 0, 0, 0, 0);
+) -> (OriginZeroLine, OriginZeroLine, u16, OriginZeroLine, OriginZeroLine, u16) {
+ let (mut col_min, mut col_max, mut col_max_span) = (OriginZeroLine(0), OriginZeroLine(0), 0);
+ let (mut row_min, mut row_max, mut row_max_span) = (OriginZeroLine(0), OriginZeroLine(0), 0);
children_iter.for_each(|child_style: &Style| {
// Note: that the children reference the lines in between (and around) the tracks not tracks themselves,
// and thus we must subtract 1 to get an accurate estimate of the number of tracks
@@ -89,8 +90,11 @@ fn get_known_child_positions<'a>(
///
/// Values are returned in origin-zero coordinates
#[inline]
-fn child_min_line_max_line_span(line: Line<GridPlacement>, explicit_track_count: u16) -> (i16, i16, u16) {
- use GridPlacement::*;
+fn child_min_line_max_line_span(
+ line: Line<GridPlacement>,
+ explicit_track_count: u16,
+) -> (OriginZeroLine, OriginZeroLine, u16) {
+ use GenericGridPlacement::*;
// 8.3.1. Grid Placement Conflict Handling
// A. If the placement for a grid item contains two lines, and the start line is further end-ward than the end line, swap the two lines.
@@ -98,58 +102,55 @@ fn child_min_line_max_line_span(line: Line<GridPlacement>, explicit_track_count:
// C. If the placement contains two spans, remove the one contributed by the end grid-placement property.
// D. If the placement contains only a span for a named line, replace it with a span of 1.
- let into_oz = |grid_line: i16| css_grid_line_into_origin_zero_coords(grid_line, explicit_track_count);
+ // Convert line into origin-zero coordinates before attempting to analyze
+ let oz_line = line.into_origin_zero(explicit_track_count);
- let min = match (line.start, line.end) {
+ let min = match (oz_line.start, oz_line.end) {
// Both tracks specified
(Line(track1), Line(track2)) => {
- let track1_oz = into_oz(track1);
- let track2_oz = into_oz(track2);
// See rules A and B above
- if track1_oz == track2_oz {
- track1_oz
+ if track1 == track2 {
+ track1
} else {
- min(track1_oz, track2_oz)
+ min(track1, track2)
}
}
// Start track specified
- (Line(track), Auto) => into_oz(track),
- (Line(track), Span(_)) => into_oz(track),
+ (Line(track), Auto) => track,
+ (Line(track), Span(_)) => track,
// End track specified
- (Auto, Line(track)) => into_oz(track),
- (Span(span), Line(track)) => into_oz(track) - (span as i16),
+ (Auto, Line(track)) => track,
+ (Span(span), Line(track)) => track - span,
// Only spans or autos
- // We ignore spans here by returning 1 which never effect the estimate as these are accounted for separately
- (Auto | Span(_), Auto | Span(_)) => 1,
+ // We ignore spans here by returning 0 which never effect the estimate as these are accounted for separately
+ (Auto | Span(_), Auto | Span(_)) => OriginZeroLine(0),
};
- let max = match (line.start, line.end) {
+ let max = match (oz_line.start, oz_line.end) {
// Both tracks specified
(Line(track1), Line(track2)) => {
- let track1_oz = into_oz(track1);
- let track2_oz = into_oz(track2);
// See rules A and B above
- if track1_oz == track2_oz {
- track1_oz + 1
+ if track1 == track2 {
+ track1 + 1
} else {
- max(track1_oz, track2_oz)
+ max(track1, track2)
}
}
// Start track specified
- (Line(track), Auto) => into_oz(track) + 1,
- (Line(track), Span(span)) => into_oz(track) + (span as i16),
+ (Line(track), Auto) => track + 1,
+ (Line(track), Span(span)) => track + span,
// End track specified
- (Auto, Line(track)) => into_oz(track),
- (Span(_), Line(track)) => into_oz(track),
+ (Auto, Line(track)) => track,
+ (Span(_), Line(track)) => track,
// Only spans or autos
- // We ignore spans here by returning 1 which never effect the estimate as these are accounted for separately
- (Auto | Span(_), Auto | Span(_)) => 1,
+ // We ignore spans here by returning 0 which never effect the estimate as these are accounted for separately
+ (Auto | Span(_), Auto | Span(_)) => OriginZeroLine(0),
};
// Calculate span only for indefinitely placed items as we don't need for other items (whose required space will
@@ -167,22 +168,23 @@ fn child_min_line_max_line_span(line: Line<GridPlacement>, explicit_track_count:
mod tests {
mod test_child_min_max_line {
use super::super::child_min_line_max_line_span;
+ use super::super::OriginZeroLine;
use crate::geometry::Line;
- use crate::style::GridPlacement::*;
+ use crate::style_helpers::*;
#[test]
fn child_min_max_line_auto() {
- let (min_col, max_col, span) = child_min_line_max_line_span(Line { start: Line(5), end: Span(6) }, 6);
- assert_eq!(min_col, 4);
- assert_eq!(max_col, 10);
+ let (min_col, max_col, span) = child_min_line_max_line_span(Line { start: line(5), end: span(6) }, 6);
+ assert_eq!(min_col, OriginZeroLine(4));
+ assert_eq!(max_col, OriginZeroLine(10));
assert_eq!(span, 1);
}
#[test]
fn child_min_max_line_negative_track() {
- let (min_col, max_col, span) = child_min_line_max_line_span(Line { start: Line(-5), end: Span(3) }, 6);
- assert_eq!(min_col, 2);
- assert_eq!(max_col, 5);
+ let (min_col, max_col, span) = child_min_line_max_line_span(Line { start: line(-5), end: span(3) }, 6);
+ assert_eq!(min_col, OriginZeroLine(2));
+ assert_eq!(max_col, OriginZeroLine(5));
assert_eq!(span, 1);
}
}
@@ -190,15 +192,15 @@ mod tests {
mod test_intial_grid_sizing {
use super::super::compute_grid_size_estimate;
use crate::compute::grid::util::test_helpers::*;
- use crate::style::GridPlacement::*;
+ use crate::style_helpers::*;
#[test]
fn explicit_grid_sizing_with_children() {
let explicit_col_count = 6;
let explicit_row_count = 8;
let child_styles = vec![
- (Line(1), Span(2), Line(2), Auto).into_grid_child(),
- (Line(-4), Auto, Line(-2), Auto).into_grid_child(),
+ (line(1), span(2), line(2), auto()).into_grid_child(),
+ (line(-4), auto(), line(-2), auto()).into_grid_child(),
];
let (inline, block) =
compute_grid_size_estimate(explicit_col_count, explicit_row_count, child_styles.iter());
@@ -215,8 +217,8 @@ mod tests {
let explicit_col_count = 4;
let explicit_row_count = 4;
let child_styles = vec![
- (Line(-6), Span(2), Line(-8), Auto).into_grid_child(),
- (Line(4), Auto, Line(3), Auto).into_grid_child(),
+ (line(-6), span(2), line(-8), auto()).into_grid_child(),
+ (line(4), auto(), line(3), auto()).into_grid_child(),
];
let (inline, block) =
compute_grid_size_estimate(explicit_col_count, explicit_row_count, child_styles.iter());
diff --git a/src/compute/grid/mod.rs b/src/compute/grid/mod.rs
index 52c1aaa83..eee1dc31d 100644
--- a/src/compute/grid/mod.rs
+++ b/src/compute/grid/mod.rs
@@ -16,7 +16,8 @@ use implicit_grid::compute_grid_size_estimate;
use placement::place_grid_items;
use track_sizing::{determine_if_item_crosses_flexible_tracks, resolve_item_track_indexes, track_sizing_algorithm};
use types::{CellOccupancyMatrix, GridTrack};
-use util::coordinates::css_grid_line_into_origin_zero_coords;
+
+pub(crate) use types::{GridCoordinate, GridLine, OriginZeroLine};
#[cfg(feature = "debug")]
use crate::debug::NODE_LOGGER;
@@ -285,22 +286,22 @@ pub fn compute(
if child_style.position == Position::Absolute {
// Convert grid-col-{start/end} into Option's of indexes into the columns vector
// The Option is None if the style property is Auto and an unresolvable Span
- let maybe_grid_cols = child_style.grid_column.resolve_absolutely_positioned_grid_tracks();
- let maybe_col_indexes = maybe_grid_cols.map(|maybe_grid_line| {
- maybe_grid_line.map(|grid_line| {
- let oz_line = css_grid_line_into_origin_zero_coords(grid_line, final_col_counts.explicit);
- final_col_counts.oz_line_to_grid_track_vec_index(oz_line) as usize
- })
- });
+ let maybe_col_indexes = child_style
+ .grid_column
+ .into_origin_zero(final_col_counts.explicit)
+ .resolve_absolutely_positioned_grid_tracks()
+ .map(|maybe_grid_line| {
+ maybe_grid_line.map(|line: OriginZeroLine| line.into_track_vec_index(final_col_counts))
+ });
// Convert grid-row-{start/end} into Option's of indexes into the row vector
// The Option is None if the style property is Auto and an unresolvable Span
- let maybe_grid_rows = child_style.grid_row.resolve_absolutely_positioned_grid_tracks();
- let maybe_row_indexes = maybe_grid_rows.map(|maybe_grid_line| {
- maybe_grid_line.map(|grid_line| {
- let oz_line = css_grid_line_into_origin_zero_coords(grid_line, final_row_counts.explicit);
- final_row_counts.oz_line_to_grid_track_vec_index(oz_line) as usize
- })
- });
+ let maybe_row_indexes = child_style
+ .grid_row
+ .into_origin_zero(final_col_counts.explicit)
+ .resolve_absolutely_positioned_grid_tracks()
+ .map(|maybe_grid_line| {
+ maybe_grid_line.map(|line: OriginZeroLine| line.into_track_vec_index(final_row_counts))
+ });
let grid_area = Rect {
top: maybe_row_indexes.start.map(|index| rows[index].offset).unwrap_or(0.0),
diff --git a/src/compute/grid/placement.rs b/src/compute/grid/placement.rs
index 0c8218848..a05deb136 100644
--- a/src/compute/grid/placement.rs
+++ b/src/compute/grid/placement.rs
@@ -1,11 +1,11 @@
//! Implements placing items in the grid and resolving the implicit grid.
//! https://www.w3.org/TR/css-grid-1/#placement
use super::types::{CellOccupancyMatrix, CellOccupancyState, GridItem};
-use super::util::css_grid_line_into_origin_zero_coords;
+use super::OriginZeroLine;
use crate::axis::{AbsoluteAxis, InBothAbsAxis};
use crate::geometry::Line;
use crate::node::Node;
-use crate::style::{GridAutoFlow, GridPlacement, Style};
+use crate::style::{GridAutoFlow, OriginZeroGridPlacement, Style};
use crate::sys::Vec;
/// 8.5. Grid Item Placement Algorithm
@@ -28,22 +28,23 @@ pub(super) fn place_grid_items<'a, ChildIter>(
let explicit_row_count = cell_occupancy_matrix.track_counts(AbsoluteAxis::Vertical).explicit;
move |(index, node, style): (usize, Node, &'a Style)| -> (_, _, _, &'a Style) {
let origin_zero_placement = InBothAbsAxis {
- horizontal: style.grid_column.map(|placement| {
- placement.map_track(|track| css_grid_line_into_origin_zero_coords(track, explicit_col_count))
- }),
- vertical: style.grid_row.map(|placement| {
- placement.map_track(|track| css_grid_line_into_origin_zero_coords(track, explicit_row_count))
- }),
+ horizontal: style.grid_column.map(|placement| placement.into_origin_zero_placement(explicit_col_count)),
+ vertical: style.grid_row.map(|placement| placement.into_origin_zero_placement(explicit_row_count)),
};
(index, node, origin_zero_placement, style)
}
};
// 1. Place children with definite positions
+ let mut idx = 0;
children_iter()
.filter(|(_, _, child_style)| child_style.grid_row.is_definite() && child_style.grid_column.is_definite())
.map(map_child_style_to_origin_zero_placement)
.for_each(|(index, child_node, child_placement, style)| {
+ idx += 1;
+ #[cfg(test)]
+ println!("Definite Item {idx}\n==============");
+
let (row_span, col_span) = place_definite_grid_item(child_placement, primary_axis);
record_grid_placement(
cell_occupancy_matrix,
@@ -59,6 +60,7 @@ pub(super) fn place_grid_items<'a, ChildIter>(
});
// 2. Place remaining children with definite secondary axis positions
+ let mut idx = 0;
children_iter()
.filter(|(_, _, child_style)| {
child_style.grid_placement(secondary_axis).is_definite()
@@ -66,6 +68,10 @@ pub(super) fn place_grid_items<'a, ChildIter>(
})
.map(map_child_style_to_origin_zero_placement)
.for_each(|(index, child_node, child_placement, style)| {
+ idx += 1;
+ #[cfg(test)]
+ println!("Definite Secondary Item {idx}\n==============");
+
let (primary_span, secondary_span) =
place_definite_secondary_axis_item(&*cell_occupancy_matrix, child_placement, grid_auto_flow);
@@ -101,7 +107,10 @@ pub(super) fn place_grid_items<'a, ChildIter>(
// 4. Position the remaining grid items
// (which either have definite position only in the secondary axis or indefinite positions in both axis)
- let mut grid_position: (u16, u16) = (0, 0);
+ let x_neg_tracks = cell_occupancy_matrix.track_counts(AbsoluteAxis::Horizontal).negative_implicit as i16;
+ let y_neg_tracks = cell_occupancy_matrix.track_counts(AbsoluteAxis::Vertical).negative_implicit as i16;
+ let grid_start_position = (OriginZeroLine(-x_neg_tracks), OriginZeroLine(-y_neg_tracks));
+ let mut grid_position = grid_start_position;
let mut idx = 0;
children_iter()
.filter(|(_, _, child_style)| !child_style.grid_placement(secondary_axis).is_definite())
@@ -109,7 +118,7 @@ pub(super) fn place_grid_items<'a, ChildIter>(
.for_each(|(index, child_node, child_placement, style)| {
idx += 1;
#[cfg(test)]
- println!("\nItem {idx}\n==============");
+ println!("\nAuto Item {idx}\n==============");
// Compute placement
let (primary_span, secondary_span) = place_indefinitely_positioned_item(
@@ -132,11 +141,11 @@ pub(super) fn place_grid_items<'a, ChildIter>(
CellOccupancyState::AutoPlaced,
);
- // If using the "dense" placement algorithm then reset the grid position back to (0, 0) ready for the next item
+ // If using the "dense" placement algorithm then reset the grid position back to grid_start_position ready for the next item
// Otherwise set it to the position of the current item so that the next item it placed after it.
grid_position = match grid_auto_flow.is_dense() {
- true => (0, 0),
- false => (primary_span.end as u16, secondary_span.start as u16),
+ true => grid_start_position,
+ false => (primary_span.end, secondary_span.start),
}
});
}
@@ -144,12 +153,12 @@ pub(super) fn place_grid_items<'a, ChildIter>(
/// 8.5. Grid Item Placement Algorithm
/// Place a single definitely placed item into the grid
fn place_definite_grid_item(
- placement: InBothAbsAxis<Line<GridPlacement>>,
+ placement: InBothAbsAxis<Line<OriginZeroGridPlacement>>,
primary_axis: AbsoluteAxis,
-) -> (Line<i16>, Line<i16>) {
+) -> (Line<OriginZeroLine>, Line<OriginZeroLine>) {
// Resolve spans to tracks
- let primary_span = placement.get(primary_axis).resolve_definite_grid_tracks();
- let secondary_span = placement.get(primary_axis.other_axis()).resolve_definite_grid_tracks();
+ let primary_span = placement.get(primary_axis).resolve_definite_grid_lines();
+ let secondary_span = placement.get(primary_axis.other_axis()).resolve_definite_grid_lines();
(primary_span, secondary_span)
}
@@ -158,21 +167,22 @@ fn place_definite_grid_item(
/// Step 2. Place remaining children with definite secondary axis positions
fn place_definite_secondary_axis_item(
cell_occupancy_matrix: &CellOccupancyMatrix,
- placement: InBothAbsAxis<Line<GridPlacement>>,
+ placement: InBothAbsAxis<Line<OriginZeroGridPlacement>>,
auto_flow: GridAutoFlow,
-) -> (Line<i16>, Line<i16>) {
+) -> (Line<OriginZeroLine>, Line<OriginZeroLine>) {
let primary_axis = auto_flow.primary_axis();
let secondary_axis = primary_axis.other_axis();
- let secondary_axis_placement = placement.get(secondary_axis).resolve_definite_grid_tracks();
+ let secondary_axis_placement = placement.get(secondary_axis).resolve_definite_grid_lines();
+ let primary_axis_grid_start_line = cell_occupancy_matrix.track_counts(primary_axis).implicit_start_line();
let starting_position = match auto_flow.is_dense() {
- true => 0,
+ true => primary_axis_grid_start_line,
false => cell_occupancy_matrix
.last_of_type(primary_axis, secondary_axis_placement.start, CellOccupancyState::AutoPlaced)
- .unwrap_or(0),
+ .unwrap_or(primary_axis_grid_start_line),
};
- let mut position: i16 = starting_position;
+ let mut position: OriginZeroLine = starting_position;
loop {
let primary_axis_placement = placement.get(primary_axis).resolve_indefinite_grid_tracks(position);
@@ -194,10 +204,10 @@ fn place_definite_secondary_axis_item(
/// Step 4. Position the remaining grid items.
fn place_indefinitely_positioned_item(
cell_occupancy_matrix: &CellOccupancyMatrix,
- placement: InBothAbsAxis<Line<GridPlacement>>,
+ placement: InBothAbsAxis<Line<OriginZeroGridPlacement>>,
auto_flow: GridAutoFlow,
- grid_position: (u16, u16),
-) -> (Line<i16>, Line<i16>) {
+ grid_position: (OriginZeroLine, OriginZeroLine),
+) -> (Line<OriginZeroLine>, Line<OriginZeroLine>) {
let primary_axis = auto_flow.primary_axis();
let primary_placement_style = placement.get(primary_axis);
@@ -206,23 +216,24 @@ fn place_indefinitely_positioned_item(
let primary_span = primary_placement_style.indefinite_span();
let secondary_span = secondary_placement_style.indefinite_span();
let has_definite_primary_axis_position = primary_placement_style.is_definite();
- let primary_axis_length = cell_occupancy_matrix.track_counts(primary_axis).len() as i16;
+ let primary_axis_grid_start_line = cell_occupancy_matrix.track_counts(primary_axis).implicit_start_line();
+ let primary_axis_grid_end_line = cell_occupancy_matrix.track_counts(primary_axis).implicit_end_line();
+ let secondary_axis_grid_start_line =
+ cell_occupancy_matrix.track_counts(primary_axis.other_axis()).implicit_start_line();
- let track_area_is_unoccupied = |primary_range, secondary_range| {
- cell_occupancy_matrix.track_area_is_unoccupied(primary_axis, primary_range, secondary_range)
+ let line_area_is_occupied = |primary_span, secondary_span| {
+ !cell_occupancy_matrix.line_area_is_unoccupied(primary_axis, primary_span, secondary_span)
};
- let tracks_to_lines = |range| cell_occupancy_matrix.tracks_to_lines(primary_axis, range);
let (mut primary_idx, mut secondary_idx) = grid_position;
if has_definite_primary_axis_position {
- let definite_primary_placement = primary_placement_style.resolve_definite_grid_tracks();
- let defined_primary_idx =
- cell_occupancy_matrix.lines_to_tracks(primary_axis.other_axis(), definite_primary_placement).start as u16;
+ let definite_primary_placement = primary_placement_style.resolve_definite_grid_lines();
+ let defined_primary_idx = definite_primary_placement.start;
// Compute starting position for search
- if defined_primary_idx < primary_idx && secondary_idx != 0 {
- secondary_idx = 0;
+ if defined_primary_idx < primary_idx && secondary_idx != secondary_axis_grid_start_line {
+ secondary_idx = secondary_axis_grid_start_line;
primary_idx = defined_primary_idx + 1;
} else {
primary_idx = defined_primary_idx;
@@ -231,43 +242,43 @@ fn place_indefinitely_positioned_item(
// Item has fixed primary axis position: so we simply increment the secondary axis position
// until we find a space that the item fits in
loop {
- let primary_range = (primary_idx as i16)..((primary_idx + primary_span) as i16);
- let secondary_range = (secondary_idx as i16)..((secondary_idx + secondary_span) as i16);
-
- let place_here = track_area_is_unoccupied(primary_range.clone(), secondary_range.clone());
- if place_here {
- let primary_span = tracks_to_lines(primary_range);
- let secondary_span = tracks_to_lines(secondary_range);
- return (primary_span, secondary_span);
+ let primary_span = Line { start: primary_idx, end: primary_idx + primary_span };
+ let secondary_span = Line { start: secondary_idx, end: secondary_idx + secondary_span };
+
+ // If area is occupied, increment the index and try again
+ if line_area_is_occupied(primary_span, secondary_span) {
+ secondary_idx += 1;
+ continue;
}
- secondary_idx += 1;
+ // Once we find a free space, return that position
+ return (primary_span, secondary_span);
}
} else {
// Item does not have any fixed axis, so we search along the primary axis until we hit the end of the already
// existent tracks, and then we reset the primary axis back to zero and increment the secondary axis index.
// We continue in this vein until we find a space that the item fits in.
loop {
- let primary_range = (primary_idx as i16)..((primary_idx + primary_span) as i16);
- let secondary_range = (secondary_idx as i16)..((secondary_idx + secondary_span) as i16);
-
- // Check if item fits in it's current position, and if so place it there
- let primary_out_of_bounds = primary_range.end > primary_axis_length;
- let place_here =
- !primary_out_of_bounds && track_area_is_unoccupied(primary_range.clone(), secondary_range.clone());
- if place_here {
- let primary_span = tracks_to_lines(primary_range);
- let secondary_span = tracks_to_lines(secondary_range);
- return (primary_span, secondary_span);
- }
+ let primary_span = Line { start: primary_idx, end: primary_idx + primary_span };
+ let secondary_span = Line { start: secondary_idx, end: secondary_idx + secondary_span };
- // Else check the next position
+ // If the primary index is out of bounds, then increment the secondary index and reset the primary
+ // index back to the start of the grid
+ let primary_out_of_bounds = primary_span.end > primary_axis_grid_end_line;
if primary_out_of_bounds {
secondary_idx += 1;
- primary_idx = 0;
- } else {
+ primary_idx = primary_axis_grid_start_line;
+ continue;
+ }
+
+ // If area is occupied, increment the primary index and try again
+ if line_area_is_occupied(primary_span, secondary_span) {
primary_idx += 1;
+ continue;
}
+
+ // Once we find a free space that's in bounds, return that position
+ return (primary_span, secondary_span);
}
}
}
@@ -282,8 +293,8 @@ fn record_grid_placement(
index: usize,
style: &Style,
primary_axis: AbsoluteAxis,
- primary_span: Line<i16>,
- secondary_span: Line<i16>,
+ primary_span: Line<OriginZeroLine>,
+ secondary_span: Line<OriginZeroLine>,
placement_type: CellOccupancyState,
) {
#[cfg(test)]
@@ -321,7 +332,7 @@ mod tests {
use crate::compute::grid::util::*;
use crate::compute::grid::CellOccupancyMatrix;
use crate::prelude::*;
- use crate::style::{GridAutoFlow, GridPlacement::*};
+ use crate::style::GridAutoFlow;
use slotmap::SlotMap;
use super::super::place_grid_items;
@@ -355,7 +366,7 @@ mod tests {
{
assert_eq!(item.node, *node);
let actual_placement = (item.column.start, item.column.end, item.row.start, item.row.end);
- assert_eq!(actual_placement, *expected_placement, "Item {idx} (0-indexed)");
+ assert_eq!(actual_placement, (*expected_placement).into_oz(), "Item {idx} (0-indexed)");
}
// Assert that the correct number of implicit rows have been generated
@@ -374,10 +385,10 @@ mod tests {
let mut sm = SlotMap::new();
vec![
// node, style (grid coords), expected_placement (oz coords)
- (1, sm.insert(()), (Line(1), Auto, Line(1), Auto).into_grid_child(), (0, 1, 0, 1)),
- (2, sm.insert(()), (Line(-4), Auto, Line(-3), Auto).into_grid_child(), (-1, 0, 0, 1)),
- (3, sm.insert(()), (Line(-3), Auto, Line(-4), Auto).into_grid_child(), (0, 1, -1, 0)),
- (4, sm.insert(()), (Line(3), Span(2), Line(5), Auto).into_grid_child(), (2, 4, 4, 5)),
+ (1, sm.insert(()), (line(1), auto(), line(1), auto()).into_grid_child(), (0, 1, 0, 1)),
+ (2, sm.insert(()), (line(-4), auto(), line(-3), auto()).into_grid_child(), (-1, 0, 0, 1)),
+ (3, sm.insert(()), (line(-3), auto(), line(-4), auto()).into_grid_child(), (0, 1, -1, 0)),
+ (4, sm.insert(()), (line(3), span(2), line(5), auto()).into_grid_child(), (2, 4, 4, 5)),
]
};
let expected_cols = TrackCounts { negative_implicit: 1, explicit: 2, positive_implicit: 2 };
@@ -385,6 +396,26 @@ mod tests {
placement_test_runner(explicit_col_count, explicit_row_count, children, expected_cols, expected_rows, flow);
}
+ #[test]
+ fn test_placement_spanning_origin() {
+ let flow = GridAutoFlow::Row;
+ let explicit_col_count = 2;
+ let explicit_row_count = 2;
+ let children = {
+ let mut sm = SlotMap::new();
+ vec![
+ // node, style (grid coords), expected_placement (oz coords)
+ (1, sm.insert(()), (line(-1), line(-1), line(-1), line(-1)).into_grid_child(), (2, 3, 2, 3)),
+ (2, sm.insert(()), (line(-1), span(2), line(-1), span(2)).into_grid_child(), (2, 4, 2, 4)),
+ (3, sm.insert(()), (line(-4), line(-4), line(-4), line(-4)).into_grid_child(), (-1, 0, -1, 0)),
+ (4, sm.insert(()), (line(-4), span(2), line(-4), span(2)).into_grid_child(), (-1, 1, -1, 1)),
+ ]
+ };
+ let expected_cols = TrackCounts { negative_implicit: 1, explicit: 2, positive_implicit: 2 };
+ let expected_rows = TrackCounts { negative_implicit: 1, explicit: 2, positive_implicit: 2 };
+ placement_test_runner(explicit_col_count, explicit_row_count, children, expected_cols, expected_rows, flow);
+ }
+
#[test]
fn test_only_auto_placement_row_flow() {
let flow = GridAutoFlow::Row;
@@ -392,7 +423,7 @@ mod tests {
let explicit_row_count = 2;
let children = {
let mut sm = SlotMap::new();
- let auto_child = (Auto, Auto, Auto, Auto).into_grid_child();
+ let auto_child = (auto(), auto(), auto(), auto()).into_grid_child();
vec![
// output order, node, style (grid coords), expected_placement (oz coords)
(1, sm.insert(()), auto_child.clone(), (0, 1, 0, 1)),
@@ -417,7 +448,7 @@ mod tests {
let explicit_row_count = 2;
let children = {
let mut sm = SlotMap::new();
- let auto_child = (Auto, Auto, Auto, Auto).into_grid_child();
+ let auto_child = (auto(), auto(), auto(), auto()).into_grid_child();
vec![
// output order, node, style (grid coords), expected_placement (oz coords)
(1, sm.insert(()), auto_child.clone(), (0, 1, 0, 1)),
@@ -444,7 +475,7 @@ mod tests {
let mut sm = SlotMap::new();
vec![
// output order, node, style (grid coords), expected_placement (oz coords)
- (1, sm.insert(()), (Span(5), Auto, Auto, Auto).into_grid_child(), (0, 5, 0, 1)),
+ (1, sm.insert(()), (span(5), auto(), auto(), auto()).into_grid_child(), (0, 5, 0, 1)),
]
};
let expected_cols = TrackCounts { negative_implicit: 0, explicit: 2, positive_implicit: 3 };
@@ -461,10 +492,10 @@ mod tests {
let mut sm = SlotMap::new();
vec![
// output order, node, style (grid coords), expected_placement (oz coords)
- (1, sm.insert(()), (Span(2), Auto, Line(1), Auto).into_grid_child(), (0, 2, 0, 1)),
- (2, sm.insert(()), (Auto, Auto, Line(2), Auto).into_grid_child(), (0, 1, 1, 2)),
- (3, sm.insert(()), (Auto, Auto, Line(1), Auto).into_grid_child(), (2, 3, 0, 1)),
- (4, sm.insert(()), (Auto, Auto, Line(4), Auto).into_grid_child(), (0, 1, 3, 4)),
+ (1, sm.insert(()), (span(2), auto(), line(1), auto()).into_grid_child(), (0, 2, 0, 1)),
+ (2, sm.insert(()), (auto(), auto(), line(2), auto()).into_grid_child(), (0, 1, 1, 2)),
+ (3, sm.insert(()), (auto(), auto(), line(1), auto()).into_grid_child(), (2, 3, 0, 1)),
+ (4, sm.insert(()), (auto(), auto(), line(4), auto()).into_grid_child(), (0, 1, 3, 4)),
]
};
let expected_cols = TrackCounts { negative_implicit: 0, explicit: 2, positive_implicit: 1 };
@@ -481,9 +512,9 @@ mod tests {
let mut sm = SlotMap::new();
vec![
// output order, node, style (grid coords), expected_placement (oz coords)
- (2, sm.insert(()), (Auto, Auto, Line(2), Auto).into_grid_child(), (0, 1, 1, 2)),
- (1, sm.insert(()), (Line(-4), Auto, Line(2), Auto).into_grid_child(), (-1, 0, 1, 2)),
- (3, sm.insert(()), (Auto, Auto, Line(1), Auto).into_grid_child(), (0, 1, 0, 1)),
+ (2, sm.insert(()), (auto(), auto(), line(2), auto()).into_grid_child(), (0, 1, 1, 2)),
+ (1, sm.insert(()), (line(-4), auto(), line(2), auto()).into_grid_child(), (-1, 0, 1, 2)),
+ (3, sm.insert(()), (auto(), auto(), line(1), auto()).into_grid_child(), (-1, 0, 0, 1)),
]
};
let expected_cols = TrackCounts { negative_implicit: 1, explicit: 2, positive_implicit: 0 };
@@ -500,9 +531,9 @@ mod tests {
let mut sm = SlotMap::new();
vec![
// output order, node, style (grid coords), expected_placement (oz coords)
- (1, sm.insert(()), (Line(2), Auto, Line(1), Auto).into_grid_child(), (1, 2, 0, 1)), // Definitely positioned in column 2
- (2, sm.insert(()), (Span(2), Auto, Auto, Auto).into_grid_child(), (2, 4, 0, 1)), // Spans 2 columns, so positioned after item 1
- (3, sm.insert(()), (Auto, Auto, Auto, Auto).into_grid_child(), (0, 1, 0, 1)), // Spans 1 column, so should be positioned before item 1
+ (1, sm.insert(()), (line(2), auto(), line(1), auto()).into_grid_child(), (1, 2, 0, 1)), // Definitely positioned in column 2
+ (2, sm.insert(()), (span(2), auto(), auto(), auto()).into_grid_child(), (2, 4, 0, 1)), // Spans 2 columns, so positioned after item 1
+ (3, sm.insert(()), (auto(), auto(), auto(), auto()).into_grid_child(), (0, 1, 0, 1)), // Spans 1 column, so should be positioned before item 1
]
};
let expected_cols = TrackCounts { negative_implicit: 0, explicit: 4, positive_implicit: 0 };
@@ -519,14 +550,33 @@ mod tests {
let mut sm = SlotMap::new();
vec![
// output order, node, style (grid coords), expected_placement (oz coords)
- (1, sm.insert(()), (Auto, Span(3), Auto, Auto).into_grid_child(), (0, 3, 0, 1)), // Width 3
- (2, sm.insert(()), (Auto, Span(3), Auto, Auto).into_grid_child(), (0, 3, 1, 2)), // Width 3 (wraps to next row)
- (3, sm.insert(()), (Auto, Span(1), Auto, Auto).into_grid_child(), (3, 4, 1, 2)), // Width 1 (uses second row as we're already on it)
+ (1, sm.insert(()), (auto(), span(3), auto(), auto()).into_grid_child(), (0, 3, 0, 1)), // Width 3
+ (2, sm.insert(()), (auto(), span(3), auto(), auto()).into_grid_child(), (0, 3, 1, 2)), // Width 3 (wraps to next row)
+ (3, sm.insert(()), (auto(), span(1), auto(), auto()).into_grid_child(), (3, 4, 1, 2)), // Width 1 (uses second row as we're already on it)
]
};
let expected_cols = TrackCounts { negative_implicit: 0, explicit: 4, positive_implicit: 0 };
let expected_rows = TrackCounts { negative_implicit: 0, explicit: 4, positive_implicit: 0 };
placement_test_runner(explicit_col_count, explicit_row_count, children, expected_cols, expected_rows, flow);
}
+
+ #[test]
+ fn test_auto_placement_in_negative_tracks() {
+ let flow = GridAutoFlow::RowDense;
+ let explicit_col_count = 2;
+ let explicit_row_count = 2;
+ let children = {
+ let mut sm = SlotMap::new();
+ vec![
+ // output order, node, style (grid coords), expected_placement (oz coords)
+ (1, sm.insert(()), (line(-5), auto(), line(1), auto()).into_grid_child(), (-2, -1, 0, 1)), // Row 1. Definitely positioned in column -2
+ (2, sm.insert(()), (auto(), auto(), line(2), auto()).into_grid_child(), (-2, -1, 1, 2)), // Row 2. Auto positioned in column -2
+ (3, sm.insert(()), (auto(), auto(), auto(), auto()).into_grid_child(), (-1, 0, 0, 1)), // Row 1. Auto positioned in column -1
+ ]
+ };
+ let expected_cols = TrackCounts { negative_implicit: 2, explicit: 2, positive_implicit: 0 };
+ let expected_rows = TrackCounts { negative_implicit: 0, explicit: 2, positive_implicit: 0 };
+ placement_test_runner(explicit_col_count, explicit_row_count, children, expected_cols, expected_rows, flow);
+ }
}
}
diff --git a/src/compute/grid/track_sizing.rs b/src/compute/grid/track_sizing.rs
index a2ca95531..d001ae218 100644
--- a/src/compute/grid/track_sizing.rs
+++ b/src/compute/grid/track_sizing.rs
@@ -136,8 +136,8 @@ pub(super) fn compute_alignment_gutter_adjustment(
/// Convert origin-zero coordinates track placement in grid track vector indexes
pub(super) fn resolve_item_track_indexes(items: &mut [GridItem], column_counts: TrackCounts, row_counts: TrackCounts) {
for item in items {
- item.column_indexes = item.column.map(|oz_index| column_counts.oz_line_to_grid_track_vec_index(oz_index));
- item.row_indexes = item.row.map(|oz_index| row_counts.oz_line_to_grid_track_vec_index(oz_index));
+ item.column_indexes = item.column.map(|line| line.into_track_vec_index(column_counts) as u16);
+ item.row_indexes = item.row.map(|line| line.into_track_vec_index(row_counts) as u16);
}
}
diff --git a/src/compute/grid/types/cell_occupancy.rs b/src/compute/grid/types/cell_occupancy.rs
index 8fa9450d2..35b3d5cef 100644
--- a/src/compute/grid/types/cell_occupancy.rs
+++ b/src/compute/grid/types/cell_occupancy.rs
@@ -1,6 +1,7 @@
//! Contains CellOccupancyMatrix used to track occupied cells during grid placement
use super::TrackCounts;
use crate::axis::AbsoluteAxis;
+use crate::compute::grid::OriginZeroLine;
use crate::geometry::Line;
use crate::sys::Vec;
use core::cmp::{max, min};
@@ -140,8 +141,8 @@ impl CellOccupancyMatrix {
pub fn mark_area_as(
&mut self,
primary_axis: AbsoluteAxis,
- primary_span: Line<i16>,
- secondary_span: Line<i16>,
+ primary_span: Line<OriginZeroLine>,
+ secondary_span: Line<OriginZeroLine>,
value: CellOccupancyState,
) {
let (row_span, column_span) = match primary_axis {
@@ -168,25 +169,13 @@ impl CellOccupancyMatrix {
}
}
- /// Converts a span of grid lines in OriginZero coordinates into a range a tracks suitable
- /// for indexing into this CellOccupancyMatrix
- pub fn lines_to_tracks(&self, axis: AbsoluteAxis, span: Line<i16>) -> Range<i16> {
- self.track_counts(axis).oz_line_range_to_track_range(span)
- }
-
- /// Converts a range a tracks indexes from this CellOccupancyMatrix into a span of grid lines
- /// in OriginZero coordinates
- pub fn tracks_to_lines(&self, axis: AbsoluteAxis, span: Range<i16>) -> Line<i16> {
- self.track_counts(axis).track_range_to_oz_line_range(span)
- }
-
/// Determines whether a grid area specified by the bounding grid lines in OriginZero coordinates
/// is entirely unnocupied. Returns true if all grid cells within the grid area are unnocupied, else false.
pub fn line_area_is_unoccupied(
&self,
primary_axis: AbsoluteAxis,
- primary_span: Line<i16>,
- secondary_span: Line<i16>,
+ primary_span: Line<OriginZeroLine>,
+ secondary_span: Line<OriginZeroLine>,
) -> bool {
let primary_range = self.track_counts(primary_axis).oz_line_range_to_track_range(primary_span);
let secondary_range = self.track_counts(primary_axis.other_axis()).oz_line_range_to_track_range(secondary_span);
@@ -240,9 +229,14 @@ impl CellOccupancyMatrix {
/// Given an axis and a track index
/// Search backwards from the end of the track and find the last grid cell matching the specified state (if any)
/// Return the index of that cell or None.
- pub fn last_of_type(&self, track_type: AbsoluteAxis, track_index: i16, kind: CellOccupancyState) -> Option<i16> {
+ pub fn last_of_type(
+ &self,
+ track_type: AbsoluteAxis,
+ start_at: OriginZeroLine,
+ kind: CellOccupancyState,
+ ) -> Option<OriginZeroLine> {
let track_counts = self.track_counts(track_type.other_axis());
- let track_computed_index = track_counts.oz_line_to_next_track(track_index);
+ let track_computed_index = track_counts.oz_line_to_next_track(start_at);
let maybe_index = match track_type {
AbsoluteAxis::Horizontal => {
diff --git a/src/compute/grid/types/coordinates.rs b/src/compute/grid/types/coordinates.rs
new file mode 100644
index 000000000..62525a8b6
--- /dev/null
+++ b/src/compute/grid/types/coordinates.rs
@@ -0,0 +1,129 @@
+//! Taffy uses two coordinate systems to refer to grid lines (the gaps/gutters between rows/columns):
+use super::super::types::TrackCounts;
+use crate::geometry::Line;
+use core::cmp::{max, Ordering};
+use core::ops::{Add, AddAssign, Sub};
+
+/// Represents a grid line position in "CSS Grid Line" coordinates
+///
+/// "CSS Grid Line" coordinates are those used in grid-row/grid-column in the CSS grid spec:
+/// - The line at left hand (or top) edge of the explicit grid is line 1
+/// (and counts up from there)
+/// - The line at the right hand (or bottom) edge of the explicit grid is -1
+/// (and counts down from there)
+/// - 0 is not a valid index
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[repr(transparent)]
+pub struct GridLine(i16);
+
+impl From<i16> for GridLine {
+ fn from(value: i16) -> Self {
+ Self(value)
+ }
+}
+
+impl GridLine {
+ /// Returns the underlying i16
+ pub fn as_i16(self) -> i16 {
+ self.0
+ }
+
+ /// Convert into OriginZero coordinates using the specified explicit track count
+ pub(crate) fn into_origin_zero_line(self, explicit_track_count: u16) -> OriginZeroLine {
+ let explicit_line_count = explicit_track_count + 1;
+ let oz_line = match self.0.cmp(&0) {
+ Ordering::Greater => self.0 - 1,
+ Ordering::Less => self.0 + explicit_line_count as i16,
+ Ordering::Equal => panic!("Grid line of zero is invalid"),
+ };
+ OriginZeroLine(oz_line)
+ }
+}
+
+/// Represents a grid line position in "OriginZero" coordinates
+///
+/// "OriginZero" coordinates are a normalized form:
+/// - The line at left hand (or top) edge of the explicit grid is line 0
+/// - The next line to the right (or down) is 1, and so on
+/// - The next line to the left (or up) is -1, and so on
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+#[repr(transparent)]
+pub struct OriginZeroLine(pub i16);
+
+// Add and Sub with Self
+impl Add<OriginZeroLine> for OriginZeroLine {
+ type Output = Self;
+ fn add(self, rhs: OriginZeroLine) -> Self::Output {
+ OriginZeroLine(self.0 + rhs.0)
+ }
+}
+impl Sub<OriginZeroLine> for OriginZeroLine {
+ type Output = Self;
+ fn sub(self, rhs: OriginZeroLine) -> Self::Output {
+ OriginZeroLine(self.0 - rhs.0)
+ }
+}
+
+// Add and Sub with u16
+impl Add<u16> for OriginZeroLine {
+ type Output = Self;
+ fn add(self, rhs: u16) -> Self::Output {
+ OriginZeroLine(self.0 + rhs as i16)
+ }
+}
+impl AddAssign<u16> for OriginZeroLine {
+ fn add_assign(&mut self, rhs: u16) {
+ self.0 += rhs as i16;
+ }
+}
+impl Sub<u16> for OriginZeroLine {
+ type Output = Self;
+ fn sub(self, rhs: u16) -> Self::Output {
+ OriginZeroLine(self.0 - rhs as i16)
+ }
+}
+
+impl OriginZeroLine {
+ /// Converts a grid line in OriginZero coordinates into the index of that same grid line in the GridTrackVec.
+ pub(crate) fn into_track_vec_index(self, track_counts: TrackCounts) -> usize {
+ assert!(
+ self.0 >= -(track_counts.negative_implicit as i16),
+ "OriginZero grid line cannot be less than the number of negative grid lines"
+ );
+ assert!(
+ self.0 <= (track_counts.explicit + track_counts.positive_implicit) as i16,
+ "OriginZero grid line cannot be more than the number of positive grid lines"
+ );
+ 2 * ((self.0 + track_counts.negative_implicit as i16) as usize)
+ }
+
+ /// The minimum number of negative implicit track there must be if a grid item starts at this line.
+ pub(crate) fn implied_negative_implicit_tracks(self) -> u16 {
+ if self.0 < 0 {
+ self.0.unsigned_abs()
+ } else {
+ 0
+ }
+ }
+
+ /// The minimum number of positive implicit track there must be if a grid item end at this line.
+ pub(crate) fn implied_positive_implicit_tracks(self, explicit_track_count: u16) -> u16 {
+ if self.0 > explicit_track_count as i16 {
+ self.0 as u16 - explicit_track_count
+ } else {
+ 0
+ }
+ }
+}
+
+impl Line<OriginZeroLine> {
+ /// The number of tracks between the start and end lines
+ pub(crate) fn span(self) -> u16 {
+ max(self.end.0 - self.start.0, 0) as u16
+ }
+}
+
+/// A trait for the different coordinates used to define grid lines.
+pub trait GridCoordinate: Copy {}
+impl GridCoordinate for GridLine {}
+impl GridCoordinate for OriginZeroLine {}
diff --git a/src/compute/grid/types/grid_item.rs b/src/compute/grid/types/grid_item.rs
index 57fa54eb6..b38d84b15 100644
--- a/src/compute/grid/types/grid_item.rs
+++ b/src/compute/grid/types/grid_item.rs
@@ -2,6 +2,7 @@
use super::GridTrack;
use crate::axis::AbstractAxis;
use crate::compute::compute_node_layout;
+use crate::compute::grid::OriginZeroLine;
use crate::geometry::{Line, Rect, Size};
use crate::layout::{RunMode, SizingMode};
use crate::node::Node;
@@ -9,7 +10,6 @@ use crate::prelude::LayoutTree;
use crate::resolve::MaybeResolve;
use crate::style::{AvailableSpace, LengthPercentageAuto, MaxTrackSizingFunction, MinTrackSizingFunction, Style};
use crate::style_helpers::*;
-use core::cmp::max;
use core::ops::Range;
/// Represents a single grid item
@@ -26,10 +26,10 @@ pub(in super::super) struct GridItem {
/// The item's definite row-start and row-end, as resolved by the placement algorithm
/// (in origin-zero coordinates)
- pub row: Line<i16>,
+ pub row: Line<OriginZeroLine>,
/// The items definite column-start and column-end, as resolved by the placement algorithm
/// (in origin-zero coordinates)
- pub column: Line<i16>,
+ pub column: Line<OriginZeroLine>,
/// The item's margin style
pub margin: Rect<LengthPercentageAuto>,
@@ -61,8 +61,8 @@ impl GridItem {
/// Create a new item given a concrete placement in both axes
pub fn new_with_placement_style_and_order(
node: Node,
- col_span: Line<i16>,
- row_span: Line<i16>,
+ col_span: Line<OriginZeroLine>,
+ row_span: Line<OriginZeroLine>,
style: &Style,
source_order: u16,
) -> Self {
@@ -84,7 +84,7 @@ impl GridItem {
}
/// This item's placement in the specified axis in OriginZero coordinates
- pub fn placement(&self, axis: AbstractAxis) -> Line<i16> {
+ pub fn placement(&self, axis: AbstractAxis) -> Line<OriginZeroLine> {
match axis {
AbstractAxis::Block => self.row,
AbstractAxis::Inline => self.column,
@@ -110,8 +110,8 @@ impl GridItem {
/// Returns the number of tracks that this item spans in the specified axis
pub fn span(&self, axis: AbstractAxis) -> u16 {
match axis {
- AbstractAxis::Block => max(self.row.end - self.row.start, 0) as u16,
- AbstractAxis::Inline => max(self.column.end - self.column.start, 0) as u16,
+ AbstractAxis::Block => self.row.span(),
+ AbstractAxis::Inline => self.column.span(),
}
}
diff --git a/src/compute/grid/types/grid_track_counts.rs b/src/compute/grid/types/grid_track_counts.rs
index efd6745ad..8ab8ae309 100644
--- a/src/compute/grid/types/grid_track_counts.rs
+++ b/src/compute/grid/types/grid_track_counts.rs
@@ -32,7 +32,7 @@
//! - Index 1 is the leftmost track of the implict grid. Index 3 is the second leftmost track, etc.
//! - Index 0 is the leftmost grid line. Index 2 is the second leftmost line, etc.
//!
-use crate::geometry::Line;
+use crate::{compute::grid::OriginZeroLine, geometry::Line};
use core::ops::Range;
/// Stores the number of tracks in a given dimension.
@@ -57,35 +57,30 @@ impl TrackCounts {
pub fn len(&self) -> usize {
(self.negative_implicit + self.explicit + self.positive_implicit) as usize
}
-}
-/// Conversion functions between OriginZero coordinates and GridTrackVec indexes
-impl TrackCounts {
- /// Converts a grid line in OriginZero coordinates into the index of that same grid line in the GridTrackVec.
- pub fn oz_line_to_grid_track_vec_index(&self, index: i16) -> u16 {
- assert!(
- index >= -(self.negative_implicit as i16),
- "OriginZero grid line cannot be less than the number of negative grid lines"
- );
- assert!(
- index <= (self.explicit + self.positive_implicit) as i16,
- "OriginZero grid line cannot be more than the number of positive grid lines"
- );
- 2 * ((index + self.negative_implicit as i16) as u16)
+ /// The OriginZeroLine representing the start of the implicit grid
+ pub fn implicit_start_line(&self) -> OriginZeroLine {
+ OriginZeroLine(-(self.negative_implicit as i16))
+ }
+
+ /// The OriginZeroLine representing the end of the implicit grid
+ pub fn implicit_end_line(&self) -> OriginZeroLine {
+ OriginZeroLine((self.explicit + self.positive_implicit) as i16)
}
}
/// Conversion functions between OriginZero coordinates and CellOccupancyMatrix track indexes
+#[allow(dead_code)]
impl TrackCounts {
/// Converts a grid line in OriginZero coordinates into the track immediately
/// following that grid line as an index into the CellOccupancyMatrix.
- pub fn oz_line_to_next_track(&self, index: i16) -> i16 {
- index + (self.negative_implicit as i16)
+ pub fn oz_line_to_next_track(&self, index: OriginZeroLine) -> i16 {
+ index.0 + (self.negative_implicit as i16)
}
/// Converts start and end grid lines in OriginZero coordinates into a range of tracks
/// as indexes into the CellOccupancyMatrix
- pub fn oz_line_range_to_track_range(&self, input: Line<i16>) -> Range<i16> {
+ pub fn oz_line_range_to_track_range(&self, input: Line<OriginZeroLine>) -> Range<i16> {
let start = self.oz_line_to_next_track(input.start);
let end = self.oz_line_to_next_track(input.end); // Don't subtract 1 as output range is exclusive
start..end
@@ -93,13 +88,13 @@ impl TrackCounts {
/// Converts a track as an index into the CellOccupancyMatrix into the grid line immediately
/// preceeding that track in OriginZero coordinates.
- pub fn track_to_prev_oz_line(&self, index: u16) -> i16 {
- (index as i16) - (self.negative_implicit as i16)
+ pub fn track_to_prev_oz_line(&self, index: u16) -> OriginZeroLine {
+ OriginZeroLine((index as i16) - (self.negative_implicit as i16))
}
/// Converts a range of tracks as indexes into the CellOccupancyMatrix into
/// start and end grid lines in OriginZero coordinates
- pub fn track_range_to_oz_line_range(&self, input: Range<i16>) -> Line<i16> {
+ pub fn track_range_to_oz_line_range(&self, input: Range<i16>) -> Line<OriginZeroLine> {
let start = self.track_to_prev_oz_line(input.start as u16);
let end = self.track_to_prev_oz_line(input.end as u16); // Don't add 1 as input range is exclusive
Line { start, end }
diff --git a/src/compute/grid/types/mod.rs b/src/compute/grid/types/mod.rs
index 1260c9bfd..c9105fa1c 100644
--- a/src/compute/grid/types/mod.rs
+++ b/src/compute/grid/types/mod.rs
@@ -1,11 +1,13 @@
//! Structs and enums that are used within the grid module
mod cell_occupancy;
+mod coordinates;
mod grid_item;
mod grid_track;
mod grid_track_counts;
// Publish only locally in the grid module
pub(super) use cell_occupancy::{CellOccupancyMatrix, CellOccupancyState};
+pub(crate) use coordinates::{GridCoordinate, GridLine, OriginZeroLine};
pub(super) use grid_item::GridItem;
pub(super) use grid_track::GridTrack;
pub(super) use grid_track_counts::TrackCounts;
diff --git a/src/compute/grid/util/coordinates.rs b/src/compute/grid/util/coordinates.rs
deleted file mode 100644
index 6e8de2086..000000000
--- a/src/compute/grid/util/coordinates.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-//! Taffy uses two coordinate systems to refer to grid lines (the gaps/gutters between rows/columns):
-//!
-//! "CSS Grid Line" coordinates are those used in grid-row/grid-column in the CSS grid spec:
-//! - The line at left hand (or top) edge of the explicit grid is line 1
-//! (and counts up from there)
-//! - The line at the right hand (or bottom) edge of the explicit grid in -1
-//! (and counts down from there)
-//! - 0 is not a valid index
-//!
-//! "OriginZero" coordinates are a normalized form:
-//! - The line at left hand (or top) edge of the explicit grid is line 0
-//! - The next line to the right (or down) is 1, and so on
-//! - The next line to the left (or up) is -1, and so on
-//!
-use core::cmp::Ordering;
-
-/// Convert from CSS Grid Line coordinates to our custom OriginZero coordinates
-pub(crate) fn css_grid_line_into_origin_zero_coords(grid_line: i16, explicit_track_count: u16) -> i16 {
- let explicit_line_count = explicit_track_count + 1;
- match grid_line.cmp(&0) {
- Ordering::Greater => grid_line - 1,
- Ordering::Less => grid_line + explicit_line_count as i16,
- Ordering::Equal => panic!("Grid line of zero is invalid"),
- }
-}
-
-#[allow(dead_code)]
-/// Convert from OriginZero coordinates to CSS Grid Line coordinates
-pub(crate) fn origin_zero_coords_into_css_grid_line(origin_zero_line: i16, explicit_track_count: u16) -> i16 {
- let explicit_line_count = explicit_track_count + 1;
- if origin_zero_line >= 0 {
- origin_zero_line + 1
- } else {
- -(origin_zero_line + explicit_line_count as i16)
- }
-}
diff --git a/src/compute/grid/util/mod.rs b/src/compute/grid/util/mod.rs
index 2e5108a81..ea6a8ed2c 100644
--- a/src/compute/grid/util/mod.rs
+++ b/src/compute/grid/util/mod.rs
@@ -1,11 +1,6 @@
//! Utility functions used within the grid module
-pub(super) mod coordinates;
-
-pub(super) use coordinates::css_grid_line_into_origin_zero_coords;
-#[allow(unused_imports)]
-pub(super) use coordinates::origin_zero_coords_into_css_grid_line;
#[cfg(test)]
pub(super) mod test_helpers;
#[cfg(test)]
-pub(super) use test_helpers::{CreateChildTestNode, CreateParentTestNode};
+pub(super) use test_helpers::{CreateChildTestNode, CreateExpectedPlacement, CreateParentTestNode};
diff --git a/src/compute/grid/util/test_helpers.rs b/src/compute/grid/util/test_helpers.rs
index 5e43032c4..e129d88c5 100644
--- a/src/compute/grid/util/test_helpers.rs
+++ b/src/compute/grid/util/test_helpers.rs
@@ -1,4 +1,5 @@
//! Helpers for use in unit tests within the grid module
+use super::super::OriginZeroLine;
use crate::prelude::*;
use crate::style::{Dimension, GridPlacement, Style};
@@ -29,3 +30,12 @@ impl CreateChildTestNode for (GridPlacement, GridPlacement, GridPlacement, GridP
}
}
}
+
+pub(crate) trait CreateExpectedPlacement {
+ fn into_oz(self) -> (OriginZeroLine, OriginZeroLine, OriginZeroLine, OriginZeroLine);
+}
+impl CreateExpectedPlacement for (i16, i16, i16, i16) {
+ fn into_oz(self) -> (OriginZeroLine, OriginZeroLine, OriginZeroLine, OriginZeroLine) {
+ (OriginZeroLine(self.0), OriginZeroLine(self.1), OriginZeroLine(self.2), OriginZeroLine(self.3))
+ }
+}
diff --git a/src/style/grid.rs b/src/style/grid.rs
index 37a9f8afc..e06f49cdc 100644
--- a/src/style/grid.rs
+++ b/src/style/grid.rs
@@ -1,6 +1,7 @@
//! Style types for CSS Grid layout
use super::{AlignContent, LengthPercentage, Style};
use crate::axis::{AbsoluteAxis, AbstractAxis};
+use crate::compute::grid::{GridCoordinate, GridLine, OriginZeroLine};
use crate::geometry::{Line, MinMax};
use crate::style::AvailableSpace;
use crate::style_helpers::*;
@@ -53,30 +54,39 @@ impl GridAutoFlow {
}
}
-/// A grid line placement specification. Used for grid-[row/column]-[start/end]. Named tracks are not implemented.
+/// A grid line placement specification which is generic over the coordinate system that it uses to define
+/// grid line positions.
///
-/// Defaults to [`GridLine::Auto`]
+/// GenericGridPlacement<GridLine> is aliased as GridPlacement and is exposed to users of Taffy to define styles.
+/// GenericGridPlacement<OriginZeroLine> is aliased as OriginZeroGridPlacement and is used internally for placement computations.
///
-/// [Specification](https://www.w3.org/TR/css3-grid-layout/#typedef-grid-row-start-grid-line)
+/// See [`crate::compute::grid::type::coordinates`] for documentation on the different coordinate systems.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
-pub enum GridPlacement {
+pub enum GenericGridPlacement<LineType: GridCoordinate> {
/// Place item according to the auto-placement algorithm, and the parent's grid_auto_flow property
Auto,
/// Place item at specified line (column or row) index
- Line(i16),
+ Line(LineType),
/// Item should span specified number of tracks (columns or rows)
Span(u16),
}
+
+/// A grid line placement using the normalized OriginZero coordinates to specify line positions.
+pub(crate) type OriginZeroGridPlacement = GenericGridPlacement<OriginZeroLine>;
+
+/// A grid line placement specification. Used for grid-[row/column]-[start/end]. Named tracks are not implemented.
+///
+/// Defaults to [`GridLine::Auto`]
+///
+/// [Specification](https://www.w3.org/TR/css3-grid-layout/#typedef-grid-row-start-grid-line)
+pub type GridPlacement = GenericGridPlacement<GridLine>;
impl TaffyAuto for GridPlacement {
const AUTO: Self = Self::Auto;
}
impl TaffyGridLine for GridPlacement {
fn from_line_index(index: i16) -> Self {
- match index {
- 0 => GridPlacement::Auto,
- _ => GridPlacement::Line(index),
- }
+ GridPlacement::Line(GridLine::from(index))
}
}
impl TaffyGridLine for Line<GridPlacement> {
@@ -103,41 +113,73 @@ impl Default for GridPlacement {
impl GridPlacement {
/// Apply a mapping function if the [`GridPlacement`] is a `Track`. Otherwise return `self` unmodified.
- pub fn map_track(&self, map_fn: impl FnOnce(i16) -> i16) -> Self {
- use GridPlacement::*;
- match *self {
- Auto => Auto,
- Span(span) => Span(span),
- Line(track) => Line(map_fn(track)),
+ pub fn into_origin_zero_placement(self, explicit_track_count: u16) -> OriginZeroGridPlacement {
+ match self {
+ Self::Auto => OriginZeroGridPlacement::Auto,
+ Self::Span(span) => OriginZeroGridPlacement::Span(span),
+ // Grid line zero is an invalid index, so it gets treated as Auto
+ // See: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-row-start#values
+ Self::Line(line) => match line.as_i16() {
+ 0 => OriginZeroGridPlacement::Auto,
+ _ => OriginZeroGridPlacement::Line(line.into_origin_zero_line(explicit_track_count)),
+ },
}
}
}
-impl Line<GridPlacement> {
+impl<T: GridCoordinate> Line<GenericGridPlacement<T>> {
#[inline]
/// Whether the track position is definite in this axis (or the item will need auto placement)
/// The track position is definite if least one of the start and end positions is a track index
pub fn is_definite(&self) -> bool {
- use GridPlacement::*;
- matches!((self.start, self.end), (Line(_), _) | (_, Line(_)))
+ matches!((self.start, self.end), (GenericGridPlacement::Line(_), _) | (_, GenericGridPlacement::Line(_)))
+ }
+
+ /// Resolves the span for an indefinite placement (a placement that does not consist of two `Track`s).
+ /// Panics if called on a definite placement
+ pub fn indefinite_span(&self) -> u16 {
+ use GenericGridPlacement as GP;
+ match (self.start, self.end) {
+ (GP::Line(_), GP::Auto) => 1,
+ (GP::Auto, GP::Line(_)) => 1,
+ (GP::Auto, GP::Auto) => 1,
+ (GP::Line(_), GP::Span(span)) => span,
+ (GP::Span(span), GP::Line(_)) => span,
+ (GP::Span(span), GP::Auto) => span,
+ (GP::Auto, GP::Span(span)) => span,
+ (GP::Span(span), GP::Span(_)) => span,
+ (GP::Line(_), GP::Line(_)) => panic!("indefinite_span should only be called on indefinite grid tracks"),
+ }
+ }
+}
+
+impl Line<GridPlacement> {
+ /// Apply a mapping function if the [`GridPlacement`] is a `Track`. Otherwise return `self` unmodified.
+ pub fn into_origin_zero(&self, explicit_track_count: u16) -> Line<OriginZeroGridPlacement> {
+ Line {
+ start: self.start.into_origin_zero_placement(explicit_track_count),
+ end: self.end.into_origin_zero_placement(explicit_track_count),
+ }
}
+}
+impl Line<OriginZeroGridPlacement> {
/// If at least one of the of the start and end positions is a track index then the other end can be resolved
/// into a track index purely based on the information contained with the placement specification
- pub fn resolve_definite_grid_tracks(&self) -> Line<i16> {
- use GridPlacement as GP;
+ pub fn resolve_definite_grid_lines(&self) -> Line<OriginZeroLine> {
+ use OriginZeroGridPlacement as GP;
match (self.start, self.end) {
- (GP::Line(track1), GP::Line(track2)) if track1 != 0 && track2 != 0 => {
- if track1 == track2 {
- Line { start: track1, end: track1 + 1 }
+ (GP::Line(line1), GP::Line(line2)) => {
+ if line1 == line2 {
+ Line { start: line1, end: line1 + 1 }
} else {
- Line { start: min(track1, track2), end: max(track1, track2) }
+ Line { start: min(line1, line2), end: max(line1, line2) }
}
}
- (GP::Line(track), GP::Span(span)) => Line { start: track, end: track + span as i16 },
- (GP::Line(track), GP::Auto | GP::Line(0)) => Line { start: track, end: track + 1_i16 },
- (GP::Span(span), GP::Line(track)) => Line { start: track - span as i16, end: track },
- (GP::Auto | GP::Line(0), GP::Line(track)) => Line { start: track - 1_i16, end: track },
+ (GP::Line(line), GP::Span(span)) => Line { start: line, end: line + span },
+ (GP::Line(line), GP::Auto) => Line { start: line, end: line + 1 },
+ (GP::Span(span), GP::Line(line)) => Line { start: line - span, end: line },
+ (GP::Auto, GP::Line(line)) => Line { start: line - 1, end: line },
_ => panic!("resolve_definite_grid_tracks should only be called on definite grid tracks"),
}
}
@@ -151,53 +193,36 @@ impl Line<GridPlacement> {
///
/// When finally positioning the item, a value of None means that the item's grid area is bounded by the grid
/// container's border box on that side.
- pub fn resolve_absolutely_positioned_grid_tracks(&self) -> Line<Option<i16>> {
- use GridPlacement as GP;
+ pub fn resolve_absolutely_positioned_grid_tracks(&self) -> Line<Option<OriginZeroLine>> {
+ use OriginZeroGridPlacement as GP;
match (self.start, self.end) {
- (GP::Line(track1), GP::Line(track2)) if track1 != 0 && track2 != 0 => {
+ (GP::Line(track1), GP::Line(track2)) => {
if track1 == track2 {
Line { start: Some(track1), end: Some(track1 + 1) }
} else {
Line { start: Some(min(track1, track2)), end: Some(max(track1, track2)) }
}
}
- (GP::Line(track), GP::Span(span)) => Line { start: Some(track), end: Some(track + span as i16) },
- (GP::Line(track), GP::Auto | GP::Line(0)) => Line { start: Some(track), end: None },
- (GP::Span(span), GP::Line(track)) => Line { start: Some(track - span as i16), end: Some(track) },
- (GP::Auto | GP::Line(0), GP::Line(track)) => Line { start: None, end: Some(track) },
+ (GP::Line(track), GP::Span(span)) => Line { start: Some(track), end: Some(track + span) },
+ (GP::Line(track), GP::Auto) => Line { start: Some(track), end: None },
+ (GP::Span(span), GP::Line(track)) => Line { start: Some(track - span), end: Some(track) },
+ (GP::Auto, GP::Line(track)) => Line { start: None, end: Some(track) },
_ => Line { start: None, end: None },
}
}
/// If neither of the start and end positions is a track index then the other end can be resolved
/// into a track index if a definite start position is supplied externally
- pub fn resolve_indefinite_grid_tracks(&self, start: i16) -> Line<i16> {
- use GridPlacement as GP;
+ pub fn resolve_indefinite_grid_tracks(&self, start: OriginZeroLine) -> Line<OriginZeroLine> {
+ use OriginZeroGridPlacement as GP;
match (self.start, self.end) {
(GP::Auto, GP::Auto) => Line { start, end: start + 1 },
- (GP::Span(span), GP::Auto) => Line { start, end: start + span as i16 },
- (GP::Auto, GP::Span(span)) => Line { start, end: start + span as i16 },
- (GP::Span(span), GP::Span(_)) => Line { start, end: start + span as i16 },
+ (GP::Span(span), GP::Auto) => Line { start, end: start + span },
+ (GP::Auto, GP::Span(span)) => Line { start, end: start + span },
+ (GP::Span(span), GP::Span(_)) => Line { start, end: start + span },
_ => panic!("resolve_indefinite_grid_tracks should only be called on indefinite grid tracks"),
}
}
-
- /// Resolves the span for an indefinite placement (a placement that does not consist of two `Track`s).
- /// Panics if called on a definite placement
- pub fn indefinite_span(&self) -> u16 {
- use GridPlacement as GP;
- match (self.start, self.end) {
- (GP::Line(_), GP::Auto) => 1,
- (GP::Auto, GP::Line(_)) => 1,
- (GP::Auto, GP::Auto) => 1,
- (GP::Line(_), GP::Span(span)) => span,
- (GP::Span(span), GP::Line(_)) => span,
- (GP::Span(span), GP::Auto) => span,
- (GP::Auto, GP::Span(span)) => span,
- (GP::Span(span), GP::Span(_)) => span,
- (GP::Line(_), GP::Line(_)) => panic!("indefinite_span should only be called on indefinite grid tracks"),
- }
- }
}
/// Represents the start and end points of a GridItem within a given axis
diff --git a/src/style/mod.rs b/src/style/mod.rs
index 6d5639a3b..a424bd702 100644
--- a/src/style/mod.rs
+++ b/src/style/mod.rs
@@ -10,6 +10,8 @@ pub use self::flex::{FlexDirection, FlexWrap};
#[cfg(feature = "grid")]
mod grid;
#[cfg(feature = "grid")]
+pub(crate) use self::grid::{GenericGridPlacement, OriginZeroGridPlacement};
+#[cfg(feature = "grid")]
pub use self::grid::{
GridAutoFlow, GridPlacement, GridTrackRepetition, MaxTrackSizingFunction, MinTrackSizingFunction,
NonRepeatedTrackSizingFunction, TrackSizingFunction,
diff --git a/src/style_helpers.rs b/src/style_helpers.rs
index e2899e580..7d4d16fcf 100644
--- a/src/style_helpers.rs
+++ b/src/style_helpers.rs
@@ -16,7 +16,10 @@ pub fn repeat(
TrackSizingFunction::AutoRepeat(repetition_kind, track_list)
}
-/// Returns a GridPlacement::Line
+/// Specifies a grid line to place a grid item between in CSS Grid Line coordinates:
+/// - Positive indicies count upwards from the start (top or left) of the explicit grid
+/// - Negative indicies count downwards from the end (bottom or right) of the explicit grid
+/// - ZERO IS INVALID index, and will be treated as a GridPlacement::Auto.
pub fn line<T: TaffyGridLine>(index: i16) -> T {
T::from_line_index(index)
}
diff --git a/test_fixtures/grid_placement_auto_negative.html b/test_fixtures/grid_placement_auto_negative.html
new file mode 100644
index 000000000..2491d5b76
--- /dev/null
+++ b/test_fixtures/grid_placement_auto_negative.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <script src="../scripts/gentest/test_helper.js"></script>
+ <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+ <title>
+ Test description
+ </title>
+<head/>
+<body>
+
+<div id="test-root" style="height: 120px; width: 120px; display: grid; grid-template-columns: 40px 40px;grid-template-rows: 40px 40px;">
+ <div style="grid-row: 1;grid-column: -5;"></div>
+ <div></div>
+ <div style="grid-row: 2"></div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_placement_definite_in_secondary_axis_with_fully_definite_negative.html b/test_fixtures/grid_placement_definite_in_secondary_axis_with_fully_definite_negative.html
new file mode 100644
index 000000000..5f20f47c4
--- /dev/null
+++ b/test_fixtures/grid_placement_definite_in_secondary_axis_with_fully_definite_negative.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <script src="../scripts/gentest/test_helper.js"></script>
+ <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+ <title>
+ Test description
+ </title>
+<head/>
+<body>
+
+<div id="test-root" style="height: 120px; width: 120px; display: grid; grid-template-columns: 40px 40px;grid-template-rows: 40px 40px;">
+ <div style="grid-row: 2"></div>
+ <div style="grid-row: 2;grid-column: -4;"></div>
+ <div style="grid-row: 1;"></div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/tests/generated/grid_absolute_column_end.rs b/tests/generated/grid_absolute_column_end.rs
index 68340985e..fcb7dac1b 100644
--- a/tests/generated/grid_absolute_column_end.rs
+++ b/tests/generated/grid_absolute_column_end.rs
@@ -7,10 +7,7 @@ fn grid_absolute_column_end() {
let node0 = taffy
.new_leaf(taffy::style::Style {
position: taffy::style::Position::Absolute,
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Auto,
- end: taffy::style::GridPlacement::Line(1i16),
- },
+ grid_column: taffy::geometry::Line { start: taffy::style::GridPlacement::Auto, end: line(1i16) },
inset: taffy::geometry::Rect {
left: taffy::style::LengthPercentageAuto::Points(4f32),
right: taffy::style::LengthPercentageAuto::Points(3f32),
diff --git a/tests/generated/grid_absolute_column_start.rs b/tests/generated/grid_absolute_column_start.rs
index f6fd1c750..356c3838c 100644
--- a/tests/generated/grid_absolute_column_start.rs
+++ b/tests/generated/grid_absolute_column_start.rs
@@ -7,10 +7,7 @@ fn grid_absolute_column_start() {
let node0 = taffy
.new_leaf(taffy::style::Style {
position: taffy::style::Position::Absolute,
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
inset: taffy::geometry::Rect {
left: taffy::style::LengthPercentageAuto::Points(4f32),
right: taffy::style::LengthPercentageAuto::Points(3f32),
diff --git a/tests/generated/grid_absolute_row_end.rs b/tests/generated/grid_absolute_row_end.rs
index 542b310a3..c69c1a1d7 100644
--- a/tests/generated/grid_absolute_row_end.rs
+++ b/tests/generated/grid_absolute_row_end.rs
@@ -7,10 +7,7 @@ fn grid_absolute_row_end() {
let node0 = taffy
.new_leaf(taffy::style::Style {
position: taffy::style::Position::Absolute,
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Auto,
- end: taffy::style::GridPlacement::Line(1i16),
- },
+ grid_row: taffy::geometry::Line { start: taffy::style::GridPlacement::Auto, end: line(1i16) },
inset: taffy::geometry::Rect {
left: taffy::style::LengthPercentageAuto::Points(4f32),
right: taffy::style::LengthPercentageAuto::Points(3f32),
diff --git a/tests/generated/grid_absolute_row_start.rs b/tests/generated/grid_absolute_row_start.rs
index 6d407e9f7..96dbd90bd 100644
--- a/tests/generated/grid_absolute_row_start.rs
+++ b/tests/generated/grid_absolute_row_start.rs
@@ -7,10 +7,7 @@ fn grid_absolute_row_start() {
let node0 = taffy
.new_leaf(taffy::style::Style {
position: taffy::style::Position::Absolute,
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
inset: taffy::geometry::Rect {
left: taffy::style::LengthPercentageAuto::Points(4f32),
right: taffy::style::LengthPercentageAuto::Points(3f32),
diff --git a/tests/generated/grid_align_items_sized_center.rs b/tests/generated/grid_align_items_sized_center.rs
index 6980f62d4..cef789834 100644
--- a/tests/generated/grid_align_items_sized_center.rs
+++ b/tests/generated/grid_align_items_sized_center.rs
@@ -6,14 +6,8 @@ fn grid_align_items_sized_center() {
let mut taffy = taffy::Taffy::new();
let node0 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(20f32),
height: taffy::style::Dimension::Points(20f32),
@@ -23,14 +17,8 @@ fn grid_align_items_sized_center() {
.unwrap();
let node1 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(60f32),
height: taffy::style::Dimension::Points(60f32),
diff --git a/tests/generated/grid_align_items_sized_end.rs b/tests/generated/grid_align_items_sized_end.rs
index e2a4eb4d2..8c003bd90 100644
--- a/tests/generated/grid_align_items_sized_end.rs
+++ b/tests/generated/grid_align_items_sized_end.rs
@@ -6,14 +6,8 @@ fn grid_align_items_sized_end() {
let mut taffy = taffy::Taffy::new();
let node0 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(20f32),
height: taffy::style::Dimension::Points(20f32),
@@ -23,14 +17,8 @@ fn grid_align_items_sized_end() {
.unwrap();
let node1 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(60f32),
height: taffy::style::Dimension::Points(60f32),
diff --git a/tests/generated/grid_align_items_sized_start.rs b/tests/generated/grid_align_items_sized_start.rs
index 780adb24f..8b98ea38a 100644
--- a/tests/generated/grid_align_items_sized_start.rs
+++ b/tests/generated/grid_align_items_sized_start.rs
@@ -6,14 +6,8 @@ fn grid_align_items_sized_start() {
let mut taffy = taffy::Taffy::new();
let node0 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(20f32),
height: taffy::style::Dimension::Points(20f32),
@@ -23,14 +17,8 @@ fn grid_align_items_sized_start() {
.unwrap();
let node1 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(60f32),
height: taffy::style::Dimension::Points(60f32),
diff --git a/tests/generated/grid_align_items_sized_stretch.rs b/tests/generated/grid_align_items_sized_stretch.rs
index eaca1d8a7..be7989810 100644
--- a/tests/generated/grid_align_items_sized_stretch.rs
+++ b/tests/generated/grid_align_items_sized_stretch.rs
@@ -6,14 +6,8 @@ fn grid_align_items_sized_stretch() {
let mut taffy = taffy::Taffy::new();
let node0 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(20f32),
height: taffy::style::Dimension::Points(20f32),
@@ -23,14 +17,8 @@ fn grid_align_items_sized_stretch() {
.unwrap();
let node1 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(60f32),
height: taffy::style::Dimension::Points(60f32),
diff --git a/tests/generated/grid_justify_items_sized_center.rs b/tests/generated/grid_justify_items_sized_center.rs
index 4347c5ba1..57c788e9a 100644
--- a/tests/generated/grid_justify_items_sized_center.rs
+++ b/tests/generated/grid_justify_items_sized_center.rs
@@ -6,14 +6,8 @@ fn grid_justify_items_sized_center() {
let mut taffy = taffy::Taffy::new();
let node0 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(20f32),
height: taffy::style::Dimension::Points(20f32),
@@ -23,14 +17,8 @@ fn grid_justify_items_sized_center() {
.unwrap();
let node1 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(60f32),
height: taffy::style::Dimension::Points(60f32),
diff --git a/tests/generated/grid_justify_items_sized_end.rs b/tests/generated/grid_justify_items_sized_end.rs
index 34bae63c9..8e0b10969 100644
--- a/tests/generated/grid_justify_items_sized_end.rs
+++ b/tests/generated/grid_justify_items_sized_end.rs
@@ -6,14 +6,8 @@ fn grid_justify_items_sized_end() {
let mut taffy = taffy::Taffy::new();
let node0 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(20f32),
height: taffy::style::Dimension::Points(20f32),
@@ -23,14 +17,8 @@ fn grid_justify_items_sized_end() {
.unwrap();
let node1 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(60f32),
height: taffy::style::Dimension::Points(60f32),
diff --git a/tests/generated/grid_justify_items_sized_start.rs b/tests/generated/grid_justify_items_sized_start.rs
index ba45d0999..d72826b3d 100644
--- a/tests/generated/grid_justify_items_sized_start.rs
+++ b/tests/generated/grid_justify_items_sized_start.rs
@@ -6,14 +6,8 @@ fn grid_justify_items_sized_start() {
let mut taffy = taffy::Taffy::new();
let node0 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(20f32),
height: taffy::style::Dimension::Points(20f32),
@@ -23,14 +17,8 @@ fn grid_justify_items_sized_start() {
.unwrap();
let node1 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(60f32),
height: taffy::style::Dimension::Points(60f32),
diff --git a/tests/generated/grid_justify_items_sized_stretch.rs b/tests/generated/grid_justify_items_sized_stretch.rs
index 872d3b7b9..d254e90a9 100644
--- a/tests/generated/grid_justify_items_sized_stretch.rs
+++ b/tests/generated/grid_justify_items_sized_stretch.rs
@@ -6,14 +6,8 @@ fn grid_justify_items_sized_stretch() {
let mut taffy = taffy::Taffy::new();
let node0 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(20f32),
height: taffy::style::Dimension::Points(20f32),
@@ -23,14 +17,8 @@ fn grid_justify_items_sized_stretch() {
.unwrap();
let node1 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(3i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(3i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(60f32),
height: taffy::style::Dimension::Points(60f32),
diff --git a/tests/generated/grid_out_of_order_items.rs b/tests/generated/grid_out_of_order_items.rs
index 166ab6e5a..257b0cb5f 100644
--- a/tests/generated/grid_out_of_order_items.rs
+++ b/tests/generated/grid_out_of_order_items.rs
@@ -8,10 +8,7 @@ fn grid_out_of_order_items() {
let node1 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
let node2 = taffy
.new_leaf(taffy::style::Style {
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(35f32),
height: taffy::style::Dimension::Points(35f32),
@@ -23,14 +20,8 @@ fn grid_out_of_order_items() {
let node4 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
let node5 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
- grid_column: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(20f32),
height: taffy::style::Dimension::Points(20f32),
@@ -41,10 +32,7 @@ fn grid_out_of_order_items() {
let node6 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
let node7 = taffy
.new_leaf(taffy::style::Style {
- grid_row: taffy::geometry::Line {
- start: taffy::style::GridPlacement::Line(1i16),
- end: taffy::style::GridPlacement::Auto,
- },
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
size: taffy::geometry::Size {
width: taffy::style::Dimension::Points(10f32),
height: taffy::style::Dimension::Points(10f32),
diff --git a/tests/generated/grid_placement_auto_negative.rs b/tests/generated/grid_placement_auto_negative.rs
new file mode 100644
index 000000000..d0323261d
--- /dev/null
+++ b/tests/generated/grid_placement_auto_negative.rs
@@ -0,0 +1,60 @@
+#[test]
+fn grid_placement_auto_negative() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(-5i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node1 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node2 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(2i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Grid,
+ grid_template_rows: vec![points(40f32), points(40f32)],
+ grid_template_columns: vec![points(40f32), points(40f32)],
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Points(120f32),
+ height: taffy::style::Dimension::Points(120f32),
+ },
+ ..Default::default()
+ },
+ &[node0, node1, node2],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 120f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 120f32, size.width);
+ assert_eq!(size.height, 120f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 120f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 20f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+ assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 20f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+ assert_eq!(location.x, 20f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 20f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node2).unwrap();
+ assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 20f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, location.y);
+}
diff --git a/tests/generated/grid_placement_definite_in_secondary_axis_with_fully_definite_negative.rs b/tests/generated/grid_placement_definite_in_secondary_axis_with_fully_definite_negative.rs
new file mode 100644
index 000000000..7159c01d8
--- /dev/null
+++ b/tests/generated/grid_placement_definite_in_secondary_axis_with_fully_definite_negative.rs
@@ -0,0 +1,71 @@
+#[test]
+fn grid_placement_definite_in_secondary_axis_with_fully_definite_negative() {
+ use slotmap::Key;
+ #[allow(unused_imports)]
+ use taffy::{layout::Layout, prelude::*};
+ let mut taffy = taffy::Taffy::new();
+ let node0 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(2i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node1 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(2i16), end: taffy::style::GridPlacement::Auto },
+ grid_column: taffy::geometry::Line { start: line(-4i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node2 = taffy
+ .new_leaf(taffy::style::Style {
+ grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+ ..Default::default()
+ })
+ .unwrap();
+ let node3 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+ let node = taffy
+ .new_with_children(
+ taffy::style::Style {
+ display: taffy::style::Display::Grid,
+ grid_template_rows: vec![points(40f32), points(40f32)],
+ grid_template_columns: vec![points(40f32), points(40f32)],
+ size: taffy::geometry::Size {
+ width: taffy::style::Dimension::Points(120f32),
+ height: taffy::style::Dimension::Points(120f32),
+ },
+ ..Default::default()
+ },
+ &[node0, node1, node2, node3],
+ )
+ .unwrap();
+ taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+ println!("\nComputed tree:");
+ taffy::debug::print_tree(&taffy, node);
+ println!();
+ let Layout { size, location, .. } = taffy.layout(node).unwrap();
+ assert_eq!(size.width, 120f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 120f32, size.width);
+ assert_eq!(size.height, 120f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 120f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+ assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.height);
+ assert_eq!(location.x, 40f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+ assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x);
+ assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node2).unwrap();
+ assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.height);
+ assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.y);
+ let Layout { size, location, .. } = taffy.layout(node3).unwrap();
+ assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, size.width);
+ assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, size.height);
+ assert_eq!(location.x, 40f32, "x of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, location.x);
+ assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node3.data(), 0f32, location.y);
+}
diff --git a/tests/generated/mod.rs b/tests/generated/mod.rs
index 30442ab48..0a7dd7489 100644
--- a/tests/generated/mod.rs
+++ b/tests/generated/mod.rs
@@ -412,6 +412,10 @@ mod grid_percent_width_and_margin;
#[cfg(feature = "grid")]
mod grid_percent_width_and_padding;
#[cfg(feature = "grid")]
+mod grid_placement_auto_negative;
+#[cfg(feature = "grid")]
+mod grid_placement_definite_in_secondary_axis_with_fully_definite_negative;
+#[cfg(feature = "grid")]
mod grid_relayout_vertical_text;
#[cfg(feature = "grid")]
mod grid_size_child_fixed_tracks;