Commit 714881a5 authored by Ethan Jimenez's avatar Ethan Jimenez Committed by Commit Bot

[GridNG] Implementation of NGGridLayoutAlgorithmTrackCollection

1. Refactoring `NGGridTrackRepeater` to store the `GridTrackSize` of its
   specified track definition; updating `NGGridTrackList::AddRepeater`
   to take the track sizes as a parameter and implicitly handle repeater
   indexes, which were unnecessarily specified by the caller.

   Adding grid track sizes in `NGGridTrackList` unit tests.

2. Fixing a bug in `NGGridBlockTrackCollection::FinalizeRanges` where
   ranges spanning implicit tracks after the explicit grid didn't
   resolve their respective repeater offsets correctly.

3. Introducing the concept of a "set" with the `NGGridSet` class; any
   range from the new algorithm collection is composed of distinct track
   definitions which compose a "set", see the class's definition for a
   detailed explanation of how these sets work.

4. Introducing `NGGridLayoutAlgorithmTrackCollection` - builds ranges
   and their respective sets from the `NGGridBlockTrackCollection` to be
   used in the track sizing algorithm in `NGGridLayoutAlgorithm`.

5. Adding unit tests for the new `NGGridLayoutAlgorithmTrackCollection`
   constructor and `NGGridLayoutAlgorithmTrackCollection::SetIterator`.

Bug: 1045599
Change-Id: I31036f0cf91a958ed74ada31f5dce5d9087faf49
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2272126
Commit-Queue: Ethan Jimenez <ethavar@microsoft.com>
Reviewed-by: default avatarChristian Biesinger <cbiesinger@chromium.org>
Reviewed-by: default avatarIan Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: default avatarJacques Newman <janewman@microsoft.com>
Reviewed-by: default avatarKurt Catti-Schmidt <kschmi@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#785679}
parent 3dc38308
...@@ -99,22 +99,20 @@ void NGGridLayoutAlgorithm::BuildTrackLists() { ...@@ -99,22 +99,20 @@ void NGGridLayoutAlgorithm::BuildTrackLists() {
// TODO(kschmi): Auto track repeat count should be based on the number of // TODO(kschmi): Auto track repeat count should be based on the number of
// children, rather than specified auto-column/track. // children, rather than specified auto-column/track.
NGGridTrackList implicit_columns;
NGGridTrackList implicit_rows; NGGridTrackList implicit_rows;
implicit_columns.AddRepeater( NGGridTrackList implicit_columns;
/*track_index*/ 0, /*track_count*/ 1, implicit_rows.AddRepeater(grid_style.GridAutoRows(), /* repeat_count */ 1);
/*repeat_count*/ grid_style.GridAutoColumns().size()); implicit_columns.AddRepeater(grid_style.GridAutoColumns(),
implicit_rows.AddRepeater(/*track_index*/ 0, 1 /*track_count*/, /* repeat_count */ 1);
/*repeat_count*/ grid_style.GridAutoRows().size());
// TODO(janewman): We need to implement calculation for track auto repeat // TODO(janewman): We need to implement calculation for track auto repeat
// count so this can be used outside of testing. // count so this can be used outside of testing.
column_track_collection_.SetSpecifiedTracks( column_track_collection_.SetSpecifiedTracks(
column_track_list_, automatic_column_repetitions_for_testing, column_track_list_, implicit_columns,
implicit_columns); automatic_column_repetitions_for_testing);
row_track_collection_.SetSpecifiedTracks( row_track_collection_.SetSpecifiedTracks(
row_track_list_, automatic_row_repetitions_for_testing, implicit_rows); row_track_list_, implicit_rows, automatic_row_repetitions_for_testing);
} }
void NGGridLayoutAlgorithm::EnsureTrackCoverageForGridItem( void NGGridLayoutAlgorithm::EnsureTrackCoverageForGridItem(
...@@ -149,7 +147,6 @@ void NGGridLayoutAlgorithm::AddRepeaters( ...@@ -149,7 +147,6 @@ void NGGridLayoutAlgorithm::AddRepeaters(
AutoRepeatType repeat_type, AutoRepeatType repeat_type,
NGGridTrackList& track_list) { NGGridTrackList& track_list) {
wtf_size_t repeat_start = NGGridBlockTrackCollection::kInvalidRangeIndex; wtf_size_t repeat_start = NGGridBlockTrackCollection::kInvalidRangeIndex;
wtf_size_t unique_track_count = 0;
// TODO(janewman): Track lists should live on the computed style, mirroring // TODO(janewman): Track lists should live on the computed style, mirroring
// the legacy layout's template_tracks and auto tracks vectors. For now, build // the legacy layout's template_tracks and auto tracks vectors. For now, build
// up the NG version from what already exists on the computed style. // up the NG version from what already exists on the computed style.
...@@ -157,9 +154,7 @@ void NGGridLayoutAlgorithm::AddRepeaters( ...@@ -157,9 +154,7 @@ void NGGridLayoutAlgorithm::AddRepeaters(
const GridTrackSize& current_track = template_tracks[i]; const GridTrackSize& current_track = template_tracks[i];
// If this is the insertion point for an auto repeater, add it here. // If this is the insertion point for an auto repeater, add it here.
if (!auto_tracks.IsEmpty() && i == auto_insertion_point) { if (!auto_tracks.IsEmpty() && i == auto_insertion_point) {
track_list.AddAutoRepeater(unique_track_count, auto_tracks.size(), track_list.AddAutoRepeater(auto_tracks, repeat_type);
repeat_type);
unique_track_count += auto_tracks.size();
repeat_start = NGGridBlockTrackCollection::kInvalidRangeIndex; repeat_start = NGGridBlockTrackCollection::kInvalidRangeIndex;
} }
// As the legacy implementation expands repeaters out, compress repeated // As the legacy implementation expands repeaters out, compress repeated
...@@ -183,8 +178,7 @@ void NGGridLayoutAlgorithm::AddRepeaters( ...@@ -183,8 +178,7 @@ void NGGridLayoutAlgorithm::AddRepeaters(
repeat_count = i + 1 - repeat_start; repeat_count = i + 1 - repeat_start;
DCHECK_NE(0u, repeat_count); DCHECK_NE(0u, repeat_count);
DCHECK_NE(NGGridBlockTrackCollection::kInvalidRangeIndex, repeat_count); DCHECK_NE(NGGridBlockTrackCollection::kInvalidRangeIndex, repeat_count);
track_list.AddRepeater(unique_track_count++, /*track_count*/ 1, track_list.AddRepeater({template_tracks[i]}, repeat_count);
repeat_count);
repeat_start = NGGridBlockTrackCollection::kInvalidRangeIndex; repeat_start = NGGridBlockTrackCollection::kInvalidRangeIndex;
} }
} }
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.h" #include "third_party/blink/renderer/core/layout/ng/grid/ng_grid_track_collection.h"
#include "base/check.h" #include "base/check.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
...@@ -48,6 +49,11 @@ wtf_size_t NGGridTrackCollectionBase::RangeIndexFromTrackNumber( ...@@ -48,6 +49,11 @@ wtf_size_t NGGridTrackCollectionBase::RangeIndexFromTrackNumber(
return lower; return lower;
} }
NGGridTrackCollectionBase::RangeRepeatIterator
NGGridTrackCollectionBase::RangeIterator() const {
return RangeRepeatIterator(this, 0u);
}
String NGGridTrackCollectionBase::ToString() const { String NGGridTrackCollectionBase::ToString() const {
if (RangeCount() == kInvalidRangeIndex) if (RangeCount() == kInvalidRangeIndex)
return "NGGridTrackCollection: Empty"; return "NGGridTrackCollection: Empty";
...@@ -80,6 +86,10 @@ NGGridTrackCollectionBase::RangeRepeatIterator::RangeRepeatIterator( ...@@ -80,6 +86,10 @@ NGGridTrackCollectionBase::RangeRepeatIterator::RangeRepeatIterator(
SetRangeIndex(range_index); SetRangeIndex(range_index);
} }
bool NGGridTrackCollectionBase::RangeRepeatIterator::IsAtEnd() const {
return range_index_ == kInvalidRangeIndex;
}
bool NGGridTrackCollectionBase::RangeRepeatIterator::MoveToNextRange() { bool NGGridTrackCollectionBase::RangeRepeatIterator::MoveToNextRange() {
return SetRangeIndex(range_index_ + 1); return SetRangeIndex(range_index_ + 1);
} }
...@@ -88,6 +98,10 @@ wtf_size_t NGGridTrackCollectionBase::RangeRepeatIterator::RepeatCount() const { ...@@ -88,6 +98,10 @@ wtf_size_t NGGridTrackCollectionBase::RangeRepeatIterator::RepeatCount() const {
return range_track_count_; return range_track_count_;
} }
wtf_size_t NGGridTrackCollectionBase::RangeRepeatIterator::RangeIndex() const {
return range_index_;
}
wtf_size_t NGGridTrackCollectionBase::RangeRepeatIterator::RangeTrackStart() wtf_size_t NGGridTrackCollectionBase::RangeRepeatIterator::RangeTrackStart()
const { const {
return range_track_start_; return range_track_start_;
...@@ -108,7 +122,7 @@ bool NGGridTrackCollectionBase::RangeRepeatIterator::IsRangeCollapsed() const { ...@@ -108,7 +122,7 @@ bool NGGridTrackCollectionBase::RangeRepeatIterator::IsRangeCollapsed() const {
bool NGGridTrackCollectionBase::RangeRepeatIterator::SetRangeIndex( bool NGGridTrackCollectionBase::RangeRepeatIterator::SetRangeIndex(
wtf_size_t range_index) { wtf_size_t range_index) {
if (range_index < 0 || range_index >= range_count_) { if (range_index >= range_count_) {
// Invalid index. // Invalid index.
range_index_ = kInvalidRangeIndex; range_index_ = kInvalidRangeIndex;
range_track_start_ = kInvalidRangeIndex; range_track_start_ = kInvalidRangeIndex;
...@@ -122,11 +136,11 @@ bool NGGridTrackCollectionBase::RangeRepeatIterator::SetRangeIndex( ...@@ -122,11 +136,11 @@ bool NGGridTrackCollectionBase::RangeRepeatIterator::SetRangeIndex(
return true; return true;
} }
NGGridTrackRepeater::NGGridTrackRepeater(wtf_size_t track_index, NGGridTrackRepeater::NGGridTrackRepeater(wtf_size_t repeat_index,
wtf_size_t repeat_size, wtf_size_t repeat_size,
wtf_size_t repeat_count, wtf_size_t repeat_count,
AutoRepeatType repeat_type) AutoRepeatType repeat_type)
: track_index(track_index), : repeat_index(repeat_index),
repeat_size(repeat_size), repeat_size(repeat_size),
repeat_count(repeat_count), repeat_count(repeat_count),
repeat_type(repeat_type) {} repeat_type(repeat_type) {}
...@@ -134,7 +148,7 @@ NGGridTrackRepeater::NGGridTrackRepeater(wtf_size_t track_index, ...@@ -134,7 +148,7 @@ NGGridTrackRepeater::NGGridTrackRepeater(wtf_size_t track_index,
String NGGridTrackRepeater::ToString() const { String NGGridTrackRepeater::ToString() const {
StringBuilder builder; StringBuilder builder;
builder.Append("Repeater: [Index: "); builder.Append("Repeater: [Index: ");
builder.AppendNumber<wtf_size_t>(track_index); builder.AppendNumber<wtf_size_t>(repeat_index);
builder.Append("], [RepeatSize: "); builder.Append("], [RepeatSize: ");
builder.AppendNumber<wtf_size_t>(repeat_size); builder.AppendNumber<wtf_size_t>(repeat_size);
builder.Append("], [RepeatCount: "); builder.Append("], [RepeatCount: ");
...@@ -153,10 +167,9 @@ String NGGridTrackRepeater::ToString() const { ...@@ -153,10 +167,9 @@ String NGGridTrackRepeater::ToString() const {
return builder.ToString(); return builder.ToString();
} }
NGGridTrackList::NGGridTrackList() { NGGridTrackList::NGGridTrackList()
auto_repeater_index_ = NGGridTrackCollectionBase::kInvalidRangeIndex; : auto_repeater_index_(NGGridTrackCollectionBase::kInvalidRangeIndex),
total_track_count_ = 0; total_track_count_(0) {}
}
wtf_size_t NGGridTrackList::RepeatCount(wtf_size_t index, wtf_size_t NGGridTrackList::RepeatCount(wtf_size_t index,
wtf_size_t auto_value) const { wtf_size_t auto_value) const {
...@@ -176,6 +189,16 @@ AutoRepeatType NGGridTrackList::RepeatType(wtf_size_t index) const { ...@@ -176,6 +189,16 @@ AutoRepeatType NGGridTrackList::RepeatType(wtf_size_t index) const {
return repeaters_[index].repeat_type; return repeaters_[index].repeat_type;
} }
const GridTrackSize& NGGridTrackList::RepeatTrackSize(wtf_size_t index,
wtf_size_t n) const {
DCHECK_LT(index, RepeaterCount());
DCHECK_LT(n, RepeatSize(index));
wtf_size_t repeat_index = repeaters_[index].repeat_index;
DCHECK_LT(repeat_index + n, repeater_track_sizes_.size());
return repeater_track_sizes_[repeat_index + n];
}
wtf_size_t NGGridTrackList::RepeaterCount() const { wtf_size_t NGGridTrackList::RepeaterCount() const {
return repeaters_.size(); return repeaters_.size();
} }
...@@ -184,54 +207,51 @@ wtf_size_t NGGridTrackList::TotalTrackCount() const { ...@@ -184,54 +207,51 @@ wtf_size_t NGGridTrackList::TotalTrackCount() const {
return total_track_count_; return total_track_count_;
} }
bool NGGridTrackList::AddRepeater(wtf_size_t track_index, bool NGGridTrackList::AddRepeater(
wtf_size_t track_count, const Vector<GridTrackSize>& repeater_track_sizes,
wtf_size_t repeat_count) { wtf_size_t repeat_count) {
return AddRepeater(track_index, track_count, repeat_count, return AddRepeater(repeater_track_sizes, AutoRepeatType::kNoAutoRepeat,
AutoRepeatType::kNoAutoRepeat); repeat_count);
} }
bool NGGridTrackList::AddAutoRepeater(wtf_size_t track_index, bool NGGridTrackList::AddAutoRepeater(
wtf_size_t track_count, const Vector<GridTrackSize>& repeater_track_sizes,
AutoRepeatType repeat_type) { AutoRepeatType repeat_type) {
return AddRepeater(track_index, track_count, 1u, repeat_type); return AddRepeater(repeater_track_sizes, repeat_type, 1u);
} }
bool NGGridTrackList::AddRepeater(wtf_size_t track_index, bool NGGridTrackList::AddRepeater(
wtf_size_t track_count, const Vector<GridTrackSize>& repeater_track_sizes,
wtf_size_t repeat_count, AutoRepeatType repeat_type,
AutoRepeatType repeat_type) { wtf_size_t repeat_count) {
// Ensure valid track index. if (repeat_count == 0u || repeater_track_sizes.IsEmpty())
DCHECK_NE(NGGridTrackCollectionBase::kInvalidRangeIndex, track_index); return false;
#if DCHECK_IS_ON()
// Ensure we do not skip or overlap tracks.
DCHECK(IsTrackContiguous(track_index));
#endif
// If the repeater is auto, the repeat_count should be 1. // If the repeater is auto, the repeat_count should be 1.
DCHECK(repeat_type == AutoRepeatType::kNoAutoRepeat || repeat_count == 1u); DCHECK(repeat_type == AutoRepeatType::kNoAutoRepeat || repeat_count == 1u);
// Ensure adding tracks will not overflow the total in this track list and // Ensure adding tracks will not overflow the total in this track list and
// that there is only one auto repeater per track list. // that there is only one auto repeater per track list.
wtf_size_t repeat_size = repeater_track_sizes.size();
switch (repeat_type) { switch (repeat_type) {
case AutoRepeatType::kNoAutoRepeat: case AutoRepeatType::kNoAutoRepeat:
if (track_count > AvailableTrackCount() / repeat_count) if (repeat_size > AvailableTrackCount() / repeat_count)
return false; return false;
total_track_count_ += track_count * repeat_count; total_track_count_ += repeat_size * repeat_count;
break; break;
case AutoRepeatType::kAutoFill: case AutoRepeatType::kAutoFill:
case AutoRepeatType::kAutoFit: // Intentional Fallthrough. case AutoRepeatType::kAutoFit: // Intentional Fallthrough.
if (HasAutoRepeater() || track_count > AvailableTrackCount()) if (HasAutoRepeater() || repeat_size > AvailableTrackCount())
return false; return false;
total_track_count_ += track_count; total_track_count_ += repeat_size;
// Update auto repeater index and append repeater. // Update auto repeater index and append repeater.
auto_repeater_index_ = repeaters_.size(); auto_repeater_index_ = repeaters_.size();
break; break;
} }
repeaters_.emplace_back(track_index, track_count, repeat_count, repeat_type); repeaters_.emplace_back(repeater_track_sizes_.size(), repeat_size,
repeat_count, repeat_type);
repeater_track_sizes_.AppendVector(repeater_track_sizes);
return true; return true;
} }
...@@ -256,33 +276,25 @@ wtf_size_t NGGridTrackList::AvailableTrackCount() const { ...@@ -256,33 +276,25 @@ wtf_size_t NGGridTrackList::AvailableTrackCount() const {
return NGGridTrackCollectionBase::kMaxRangeIndex - total_track_count_; return NGGridTrackCollectionBase::kMaxRangeIndex - total_track_count_;
} }
#if DCHECK_IS_ON()
bool NGGridTrackList::IsTrackContiguous(wtf_size_t track_index) const {
return repeaters_.IsEmpty() ||
(repeaters_.back().track_index + repeaters_.back().repeat_size ==
track_index);
}
#endif
void NGGridBlockTrackCollection::SetSpecifiedTracks( void NGGridBlockTrackCollection::SetSpecifiedTracks(
const NGGridTrackList& specified_tracks, const NGGridTrackList& explicit_tracks,
wtf_size_t auto_repeat_count, const NGGridTrackList& implicit_tracks,
const NGGridTrackList& implicit_tracks) { wtf_size_t auto_repeat_count) {
// The implicit track list should have only one repeater, if any. // The implicit track list should have only one repeater, if any.
DCHECK_LE(implicit_tracks.RepeaterCount(), 1u); DCHECK_LE(implicit_tracks.RepeaterCount(), 1u);
DCHECK_NE(NGGridTrackCollectionBase::kInvalidRangeIndex, auto_repeat_count); DCHECK_NE(NGGridTrackCollectionBase::kInvalidRangeIndex, auto_repeat_count);
specified_tracks_ = specified_tracks; explicit_tracks_ = explicit_tracks;
implicit_tracks_ = implicit_tracks; implicit_tracks_ = implicit_tracks;
auto_repeat_count_ = auto_repeat_count; auto_repeat_count_ = auto_repeat_count;
wtf_size_t repeater_count = specified_tracks_.RepeaterCount(); wtf_size_t repeater_count = explicit_tracks_.RepeaterCount();
wtf_size_t total_track_count = 0; wtf_size_t total_track_count = 0;
for (wtf_size_t i = 0; i < repeater_count; ++i) { for (wtf_size_t i = 0; i < repeater_count; ++i) {
wtf_size_t repeater_track_start = total_track_count + 1; wtf_size_t repeater_track_start = total_track_count + 1;
wtf_size_t repeater_track_count = wtf_size_t repeater_track_count =
specified_tracks_.RepeatCount(i, auto_repeat_count_) * explicit_tracks_.RepeatCount(i, auto_repeat_count_) *
specified_tracks_.RepeatSize(i); explicit_tracks_.RepeatSize(i);
if (repeater_track_count != 0) { if (repeater_track_count != 0) {
starting_tracks_.push_back(repeater_track_start); starting_tracks_.push_back(repeater_track_start);
ending_tracks_.push_back(repeater_track_start + repeater_track_count - 1); ending_tracks_.push_back(repeater_track_start + repeater_track_count - 1);
...@@ -322,7 +334,7 @@ void NGGridBlockTrackCollection::FinalizeRanges() { ...@@ -322,7 +334,7 @@ void NGGridBlockTrackCollection::FinalizeRanges() {
wtf_size_t next_repeater_track_start = 1u; wtf_size_t next_repeater_track_start = 1u;
wtf_size_t current_repeater_track_count = 0; wtf_size_t current_repeater_track_count = 0;
wtf_size_t total_repeater_count = specified_tracks_.RepeaterCount(); wtf_size_t total_repeater_count = explicit_tracks_.RepeaterCount();
wtf_size_t open_items_or_repeaters = 0; wtf_size_t open_items_or_repeaters = 0;
bool is_in_auto_fit_range = false; bool is_in_auto_fit_range = false;
...@@ -365,11 +377,11 @@ void NGGridBlockTrackCollection::FinalizeRanges() { ...@@ -365,11 +377,11 @@ void NGGridBlockTrackCollection::FinalizeRanges() {
break; break;
} }
is_in_auto_fit_range = specified_tracks_.RepeatType(repeater_index) == is_in_auto_fit_range = explicit_tracks_.RepeatType(repeater_index) ==
AutoRepeatType::kAutoFit; AutoRepeatType::kAutoFit;
current_repeater_track_count = current_repeater_track_count =
specified_tracks_.RepeatCount(repeater_index, auto_repeat_count_) * explicit_tracks_.RepeatCount(repeater_index, auto_repeat_count_) *
specified_tracks_.RepeatSize(repeater_index); explicit_tracks_.RepeatSize(repeater_index);
repeater_track_start = next_repeater_track_start; repeater_track_start = next_repeater_track_start;
next_repeater_track_start += current_repeater_track_count; next_repeater_track_start += current_repeater_track_count;
} }
...@@ -394,18 +406,9 @@ void NGGridBlockTrackCollection::FinalizeRanges() { ...@@ -394,18 +406,9 @@ void NGGridBlockTrackCollection::FinalizeRanges() {
range.repeater_offset = 0; range.repeater_offset = 0;
} else { } else {
// Use implicit tracks. // Use implicit tracks.
wtf_size_t implicit_repeat_size = ImplicitRepeatSize();
range.repeater_index = 0; range.repeater_index = 0;
if (range.starting_track_number == 0) { range.repeater_offset =
wtf_size_t offset_from_end = current_range_track_start - repeater_track_start;
(1 - range.starting_track_number) % implicit_repeat_size;
if (offset_from_end == implicit_repeat_size) {
range.repeater_offset = 0;
} else {
range.repeater_offset =
current_range_track_start - repeater_track_start;
}
}
} }
} else { } else {
range.is_implicit_range = false; range.is_implicit_range = false;
...@@ -422,7 +425,7 @@ void NGGridBlockTrackCollection::FinalizeRanges() { ...@@ -422,7 +425,7 @@ void NGGridBlockTrackCollection::FinalizeRanges() {
while (repeater_index != kInvalidRangeIndex && while (repeater_index != kInvalidRangeIndex &&
repeater_index < total_repeater_count - 1u) { repeater_index < total_repeater_count - 1u) {
++repeater_index; ++repeater_index;
DCHECK_EQ(0u, specified_tracks_.RepeatSize(repeater_index)); DCHECK_EQ(0u, explicit_tracks_.RepeatSize(repeater_index));
} }
#endif #endif
DCHECK_EQ(starting_tracks_index, starting_tracks_.size()); DCHECK_EQ(starting_tracks_index, starting_tracks_.size());
...@@ -435,23 +438,30 @@ void NGGridBlockTrackCollection::FinalizeRanges() { ...@@ -435,23 +438,30 @@ void NGGridBlockTrackCollection::FinalizeRanges() {
const NGGridBlockTrackCollection::Range& const NGGridBlockTrackCollection::Range&
NGGridBlockTrackCollection::RangeAtRangeIndex(wtf_size_t range_index) const { NGGridBlockTrackCollection::RangeAtRangeIndex(wtf_size_t range_index) const {
DCHECK_NE(range_index, kInvalidRangeIndex);
DCHECK_LT(range_index, ranges_.size()); DCHECK_LT(range_index, ranges_.size());
return ranges_[range_index]; return ranges_[range_index];
} }
const NGGridBlockTrackCollection::Range& const NGGridBlockTrackCollection::Range&
NGGridBlockTrackCollection::RangeAtTrackNumber(wtf_size_t track_number) const { NGGridBlockTrackCollection::RangeAtTrackNumber(wtf_size_t track_number) const {
wtf_size_t range_index = RangeIndexFromTrackNumber(track_number); wtf_size_t range_index = RangeIndexFromTrackNumber(track_number);
DCHECK_NE(range_index, kInvalidRangeIndex);
DCHECK_LT(range_index, ranges_.size()); DCHECK_LT(range_index, ranges_.size());
return ranges_[range_index]; return ranges_[range_index];
} }
const NGGridTrackList& NGGridBlockTrackCollection::ExplicitTracks() const {
return explicit_tracks_;
}
const NGGridTrackList& NGGridBlockTrackCollection::ImplicitTracks() const {
return implicit_tracks_;
}
String NGGridBlockTrackCollection::ToString() const { String NGGridBlockTrackCollection::ToString() const {
if (ranges_.IsEmpty()) { if (ranges_.IsEmpty()) {
StringBuilder builder; StringBuilder builder;
builder.Append("NGGridTrackCollection: [SpecifiedTracks: "); builder.Append("NGGridTrackCollection: [SpecifiedTracks: ");
builder.Append(specified_tracks_.ToString()); builder.Append(explicit_tracks_.ToString());
if (HasImplicitTracks()) { if (HasImplicitTracks()) {
builder.Append("], [ImplicitTracks: "); builder.Append("], [ImplicitTracks: ");
builder.Append(implicit_tracks_.ToString()); builder.Append(implicit_tracks_.ToString());
...@@ -475,9 +485,11 @@ String NGGridBlockTrackCollection::ToString() const { ...@@ -475,9 +485,11 @@ String NGGridBlockTrackCollection::ToString() const {
return NGGridTrackCollectionBase::ToString(); return NGGridTrackCollectionBase::ToString();
} }
} }
bool NGGridBlockTrackCollection::HasImplicitTracks() const { bool NGGridBlockTrackCollection::HasImplicitTracks() const {
return implicit_tracks_.RepeaterCount() != 0; return implicit_tracks_.RepeaterCount() != 0;
} }
wtf_size_t NGGridBlockTrackCollection::ImplicitRepeatSize() const { wtf_size_t NGGridBlockTrackCollection::ImplicitRepeatSize() const {
DCHECK(HasImplicitTracks()); DCHECK(HasImplicitTracks());
return implicit_tracks_.RepeatSize(0); return implicit_tracks_.RepeatSize(0);
...@@ -505,4 +517,163 @@ wtf_size_t NGGridBlockTrackCollection::RangeCount() const { ...@@ -505,4 +517,163 @@ wtf_size_t NGGridBlockTrackCollection::RangeCount() const {
return ranges_.size(); return ranges_.size();
} }
NGGridSet::NGGridSet(wtf_size_t track_count, bool is_collapsed)
: track_count_(track_count), track_size_(Length::Auto()) {
if (is_collapsed) {
// From https://www.w3.org/TR/css-grid-1/#collapsed-track:
// A collapsed track is treated as having a fixed size of '0px'.
track_size_ = GridTrackSize(Length::Fixed());
}
}
NGGridSet::NGGridSet(wtf_size_t track_count, const GridTrackSize& track_size)
: track_count_(track_count), track_size_(track_size) {}
NGGridLayoutAlgorithmTrackCollection::Range::Range(
const NGGridBlockTrackCollection::Range& block_track_range,
wtf_size_t starting_set_index)
: starting_track_number(block_track_range.starting_track_number),
track_count(block_track_range.track_count),
starting_set_index(starting_set_index),
is_collapsed(block_track_range.is_collapsed) {}
NGGridLayoutAlgorithmTrackCollection::SetIterator::SetIterator(
NGGridLayoutAlgorithmTrackCollection* collection,
wtf_size_t begin_set_index,
wtf_size_t end_set_index)
: collection_(collection),
current_set_index_(begin_set_index),
end_set_index_(end_set_index) {
DCHECK(collection_);
DCHECK_LE(current_set_index_, end_set_index_);
}
bool NGGridLayoutAlgorithmTrackCollection::SetIterator::IsAtEnd() const {
DCHECK_LE(current_set_index_, end_set_index_);
return current_set_index_ == end_set_index_;
}
bool NGGridLayoutAlgorithmTrackCollection::SetIterator::MoveToNextSet() {
current_set_index_ = std::min(current_set_index_ + 1, end_set_index_);
return current_set_index_ < end_set_index_;
}
NGGridSet& NGGridLayoutAlgorithmTrackCollection::SetIterator::CurrentSet()
const {
DCHECK_LT(current_set_index_, end_set_index_);
return collection_->SetAt(current_set_index_);
}
NGGridLayoutAlgorithmTrackCollection::NGGridLayoutAlgorithmTrackCollection(
const NGGridBlockTrackCollection& block_track_collection) {
RangeRepeatIterator range_iterator = block_track_collection.RangeIterator();
while (!range_iterator.IsAtEnd()) {
const NGGridBlockTrackCollection::Range& block_track_range =
block_track_collection.RangeAtRangeIndex(range_iterator.RangeIndex());
AppendTrackRange(block_track_range,
block_track_range.is_implicit_range
? block_track_collection.ImplicitTracks()
: block_track_collection.ExplicitTracks());
range_iterator.MoveToNextRange();
}
}
void NGGridLayoutAlgorithmTrackCollection::AppendTrackRange(
const NGGridBlockTrackCollection::Range& block_track_range,
const NGGridTrackList& specified_track_list) {
Range new_range(block_track_range, /* starting_set_index */ sets_.size());
if (block_track_range.is_collapsed ||
block_track_range.repeater_index == kInvalidRangeIndex) {
#if DCHECK_IS_ON()
// If there are no specified repeaters for this range, it must be implicit.
if (block_track_range.repeater_index == kInvalidRangeIndex)
DCHECK(block_track_range.is_implicit_range);
#endif
// Append a single element for the entire range's set.
new_range.set_count = 1;
sets_.emplace_back(block_track_range.track_count,
block_track_range.is_collapsed);
} else {
wtf_size_t repeater_size =
specified_track_list.RepeatSize(block_track_range.repeater_index);
// The number of different set elements in this range is the number of track
// definitions from |NGGridBlockTrackCollection| range's repeater clamped by
// the range's total track count if it's less than the repeater's size.
new_range.set_count =
std::min(repeater_size, block_track_range.track_count);
DCHECK_GT(new_range.set_count, 0u);
// The following two variables help compute how many tracks a set element
// compresses; suppose we want to print this range, we would circle through
// the repeater's track list, starting at the range's repeater offset,
// printing every definition until the track count for the range is covered:
//
// 1. |floor_set_track_count| is the number of times we would return to the
// range's repeater offset, meaning that every definition in the repeater's
// track list appears at least that many times within the range.
wtf_size_t floor_set_track_count = new_range.track_count / repeater_size;
// 2. The remaining track count would not complete another iteration over
// the entire repeater; this means that the first |remaining_track_count|
// definitions appear one more time in the range.
wtf_size_t remaining_track_count = new_range.track_count % repeater_size;
for (wtf_size_t i = 0; i < new_range.set_count; ++i) {
wtf_size_t set_track_count =
floor_set_track_count + ((i < remaining_track_count) ? 1 : 0);
wtf_size_t set_repeater_offset =
(block_track_range.repeater_offset + i) % repeater_size;
const GridTrackSize& set_track_size =
specified_track_list.RepeatTrackSize(block_track_range.repeater_index,
set_repeater_offset);
sets_.emplace_back(set_track_count, set_track_size);
}
}
ranges_.push_back(new_range);
}
NGGridSet& NGGridLayoutAlgorithmTrackCollection::SetAt(wtf_size_t set_index) {
DCHECK_LT(set_index, SetCount());
return sets_[set_index];
}
NGGridLayoutAlgorithmTrackCollection::SetIterator
NGGridLayoutAlgorithmTrackCollection::IteratorForRange(wtf_size_t range_index) {
DCHECK_LT(range_index, RangeCount());
const Range& range = ranges_[range_index];
DCHECK_LE(range.starting_set_index + range.set_count, SetCount());
return SetIterator(this, range.starting_set_index,
range.starting_set_index + range.set_count);
}
wtf_size_t NGGridLayoutAlgorithmTrackCollection::RangeTrackNumber(
wtf_size_t range_index) const {
DCHECK_LT(range_index, RangeCount());
return ranges_[range_index].starting_track_number;
}
wtf_size_t NGGridLayoutAlgorithmTrackCollection::RangeTrackCount(
wtf_size_t range_index) const {
DCHECK_LT(range_index, RangeCount());
return ranges_[range_index].track_count;
}
bool NGGridLayoutAlgorithmTrackCollection::IsRangeCollapsed(
wtf_size_t range_index) const {
DCHECK_LT(range_index, RangeCount());
return ranges_[range_index].is_collapsed;
}
wtf_size_t NGGridLayoutAlgorithmTrackCollection::RangeCount() const {
return ranges_.size();
}
wtf_size_t NGGridLayoutAlgorithmTrackCollection::SetCount() const {
return sets_.size();
}
} // namespace blink } // namespace blink
...@@ -23,15 +23,18 @@ class CORE_EXPORT NGGridTrackCollectionBase { ...@@ -23,15 +23,18 @@ class CORE_EXPORT NGGridTrackCollectionBase {
RangeRepeatIterator(const NGGridTrackCollectionBase* collection, RangeRepeatIterator(const NGGridTrackCollectionBase* collection,
wtf_size_t range_index); wtf_size_t range_index);
bool IsAtEnd() const;
// Moves iterator to next range, skipping over repeats in a range. Return // Moves iterator to next range, skipping over repeats in a range. Return
// true if the move was successful. // true if the move was successful.
bool MoveToNextRange(); bool MoveToNextRange();
wtf_size_t RepeatCount() const; wtf_size_t RepeatCount() const;
// Returns the index of this range in the collection.
wtf_size_t RangeIndex() const;
// Returns the track number for the start of the range. // Returns the track number for the start of the range.
wtf_size_t RangeTrackStart() const; wtf_size_t RangeTrackStart() const;
// Returns the track number at the end of the range. // Returns the track number at the end of the range.
wtf_size_t RangeTrackEnd() const; wtf_size_t RangeTrackEnd() const;
bool IsRangeCollapsed() const; bool IsRangeCollapsed() const;
private: private:
...@@ -49,6 +52,7 @@ class CORE_EXPORT NGGridTrackCollectionBase { ...@@ -49,6 +52,7 @@ class CORE_EXPORT NGGridTrackCollectionBase {
// Gets the range index for the range that contains the given track number. // Gets the range index for the range that contains the given track number.
wtf_size_t RangeIndexFromTrackNumber(wtf_size_t track_number) const; wtf_size_t RangeIndexFromTrackNumber(wtf_size_t track_number) const;
RangeRepeatIterator RangeIterator() const;
String ToString() const; String ToString() const;
protected: protected:
...@@ -67,14 +71,17 @@ class CORE_EXPORT NGGridTrackCollectionBase { ...@@ -67,14 +71,17 @@ class CORE_EXPORT NGGridTrackCollectionBase {
// Stores tracks related data by compressing repeated tracks into a single node. // Stores tracks related data by compressing repeated tracks into a single node.
struct NGGridTrackRepeater { struct NGGridTrackRepeater {
NGGridTrackRepeater(wtf_size_t track_index, NGGridTrackRepeater(wtf_size_t repeat_index,
wtf_size_t repeat_size, wtf_size_t repeat_size,
wtf_size_t repeat_count, wtf_size_t repeat_count,
AutoRepeatType repeat_type); AutoRepeatType repeat_type);
String ToString() const; String ToString() const;
bool operator==(const NGGridTrackRepeater& rhs) const; bool operator==(const NGGridTrackRepeater& rhs) const;
// Index of the first track being repeated.
wtf_size_t track_index; // |NGGridTrackList| will store the sizes for each track in this repeater
// consecutively in a single vector for all repeaters; this index specifies
// the position of the first track size that belongs to this repeater.
wtf_size_t repeat_index;
// Amount of tracks to be repeated. // Amount of tracks to be repeated.
wtf_size_t repeat_size; wtf_size_t repeat_size;
// Amount of times the group of tracks are repeated. // Amount of times the group of tracks are repeated.
...@@ -93,18 +100,18 @@ class CORE_EXPORT NGGridTrackList { ...@@ -93,18 +100,18 @@ class CORE_EXPORT NGGridTrackList {
wtf_size_t RepeatSize(wtf_size_t index) const; wtf_size_t RepeatSize(wtf_size_t index) const;
// Returns the repeat type of the repeater at |index|. // Returns the repeat type of the repeater at |index|.
AutoRepeatType RepeatType(wtf_size_t index) const; AutoRepeatType RepeatType(wtf_size_t index) const;
// Returns the size of the |n|-th specified track of the repeater at |index|.
const GridTrackSize& RepeatTrackSize(wtf_size_t index, wtf_size_t n) const;
// Returns the count of repeaters. // Returns the count of repeaters.
wtf_size_t RepeaterCount() const; wtf_size_t RepeaterCount() const;
// Returns the total count of all the tracks in this list. // Returns the total count of all the tracks in this list.
wtf_size_t TotalTrackCount() const; wtf_size_t TotalTrackCount() const;
// Adds a non-auto repeater. // Adds a non-auto repeater.
bool AddRepeater(wtf_size_t track_index, bool AddRepeater(const Vector<GridTrackSize>& repeater_track_sizes,
wtf_size_t track_count,
wtf_size_t repeat_count); wtf_size_t repeat_count);
// Adds an auto repeater. // Adds an auto repeater.
bool AddAutoRepeater(wtf_size_t track_index, bool AddAutoRepeater(const Vector<GridTrackSize>& repeater_track_sizes,
wtf_size_t track_count,
AutoRepeatType repeat_type); AutoRepeatType repeat_type);
// Returns true if this list contains an auto repeater. // Returns true if this list contains an auto repeater.
bool HasAutoRepeater(); bool HasAutoRepeater();
...@@ -115,21 +122,18 @@ class CORE_EXPORT NGGridTrackList { ...@@ -115,21 +122,18 @@ class CORE_EXPORT NGGridTrackList {
String ToString() const; String ToString() const;
private: private:
bool AddRepeater(wtf_size_t track_index, bool AddRepeater(const Vector<GridTrackSize>& repeater_track_sizes,
wtf_size_t track_count, AutoRepeatType repeat_type,
wtf_size_t repeat_count, wtf_size_t repeat_count);
AutoRepeatType repeat_type);
// Returns the amount of tracks available before overflow. // Returns the amount of tracks available before overflow.
wtf_size_t AvailableTrackCount() const; wtf_size_t AvailableTrackCount() const;
#if DCHECK_IS_ON()
// Helper to check if |track_index| does not cause a gap or overlap with the
// tracks in this list. Ensures |track_index| is equal to 1 + the last track's
// index.
bool IsTrackContiguous(wtf_size_t track_index) const;
#endif
Vector<NGGridTrackRepeater> repeaters_; Vector<NGGridTrackRepeater> repeaters_;
// Stores the track sizes of every repeater added to this list; tracks from
// the same repeater group are stored consecutively.
Vector<GridTrackSize> repeater_track_sizes_;
// The index of the automatic repeater, if there is one; |kInvalidRangeIndex| // The index of the automatic repeater, if there is one; |kInvalidRangeIndex|
// otherwise. // otherwise.
wtf_size_t auto_repeater_index_; wtf_size_t auto_repeater_index_;
...@@ -150,9 +154,9 @@ class CORE_EXPORT NGGridBlockTrackCollection ...@@ -150,9 +154,9 @@ class CORE_EXPORT NGGridBlockTrackCollection
}; };
// Sets the specified, implicit tracks, along with a given auto repeat value. // Sets the specified, implicit tracks, along with a given auto repeat value.
void SetSpecifiedTracks(const NGGridTrackList& specified_tracks, void SetSpecifiedTracks(const NGGridTrackList& explicit_tracks,
wtf_size_t auto_repeat_count, const NGGridTrackList& implicit_tracks,
const NGGridTrackList& implicit_tracks); wtf_size_t auto_repeat_count);
// Ensures that after FinalizeRanges is called, a range will start at the // Ensures that after FinalizeRanges is called, a range will start at the
// |track_number|, and a range will end at |track_number| + |span_length| // |track_number|, and a range will end at |track_number| + |span_length|
void EnsureTrackCoverage(wtf_size_t track_number, wtf_size_t span_length); void EnsureTrackCoverage(wtf_size_t track_number, wtf_size_t span_length);
...@@ -165,19 +169,16 @@ class CORE_EXPORT NGGridBlockTrackCollection ...@@ -165,19 +169,16 @@ class CORE_EXPORT NGGridBlockTrackCollection
// Returns the range at the given track. // Returns the range at the given track.
const Range& RangeAtTrackNumber(wtf_size_t track_number) const; const Range& RangeAtTrackNumber(wtf_size_t track_number) const;
const NGGridTrackList& ExplicitTracks() const;
const NGGridTrackList& ImplicitTracks() const;
String ToString() const; String ToString() const;
protected: protected:
// Returns the first track number of a range. // NGGridTrackCollectionBase overrides.
wtf_size_t RangeTrackNumber(wtf_size_t range_index) const override; wtf_size_t RangeTrackNumber(wtf_size_t range_index) const override;
// Returns the number of tracks in a range.
wtf_size_t RangeTrackCount(wtf_size_t range_index) const override; wtf_size_t RangeTrackCount(wtf_size_t range_index) const override;
// Returns true if the range at |range_index| is collapsed.
bool IsRangeCollapsed(wtf_size_t range_index) const override; bool IsRangeCollapsed(wtf_size_t range_index) const override;
// Returns the number of track ranges in the collection.
wtf_size_t RangeCount() const override; wtf_size_t RangeCount() const override;
private: private:
...@@ -190,7 +191,7 @@ class CORE_EXPORT NGGridBlockTrackCollection ...@@ -190,7 +191,7 @@ class CORE_EXPORT NGGridBlockTrackCollection
wtf_size_t auto_repeat_count_ = 0; wtf_size_t auto_repeat_count_ = 0;
// Stores the specified and implicit tracks specified by SetSpecifiedTracks. // Stores the specified and implicit tracks specified by SetSpecifiedTracks.
NGGridTrackList specified_tracks_; NGGridTrackList explicit_tracks_;
NGGridTrackList implicit_tracks_; NGGridTrackList implicit_tracks_;
// Starting and ending tracks mark where ranges will start and end. // Starting and ending tracks mark where ranges will start and end.
...@@ -200,6 +201,117 @@ class CORE_EXPORT NGGridBlockTrackCollection ...@@ -200,6 +201,117 @@ class CORE_EXPORT NGGridBlockTrackCollection
Vector<Range> ranges_; Vector<Range> ranges_;
}; };
// |NGGridBlockTrackCollection::EnsureTrackCoverage| may introduce a range start
// and/or end at the middle of any repeater from the block collection. This will
// affect how some repeated tracks within the same repeater group resolve their
// track sizes; e.g. consider the track list 'repeat(10, auto)' with a grid item
// spanning from the 3rd to the 7th track in the repeater, every track within
// the item's range will grow to fit the content of that item first.
//
// For the track sizing algorithm we want to have separate data (e.g. base size,
// growth limit, etc.) between tracks in different ranges; instead of trivially
// expanding the repeaters, which will limit our implementation to support
// relatively small track counts, we introduce the concept of a "set".
//
// A "set" is a collection of distinct track definitions that compose a range in
// |NGGridLayoutAlgorithmTrackCollection|; each set element stores the number of
// tracks within the range that share its definition. The |NGGridSet| class
// represents a single element from a set.
//
// As an example, consider the following grid definition:
// - 'grid-template-columns: repeat(4, 5px 1fr)'
// - Grid item 1 with 'grid-column: 1 / span 5'
// - Grid item 2 with 'grid-column: 2 / span 1'
// - Grid item 3 with 'grid-column: 6 / span 8'
//
// Expanding the track definitions above we would look at the explicit grid:
// | 5px | 1fr | 5px | 1fr | 5px | 1fr | 5px | 1fr |
//
// This example would produce the following ranges and their respective sets:
// Range 1: [1-1], Set 1: { 5px (1) }
// Range 2: [2-2], Set 2: { 1fr (1) }
// Range 3: [3-5], Set 3: { 5px (2) , 1fr (1) }
// Range 4: [6-8], Set 4: { 1fr (2) , 5px (1) }
// Range 5: [9-13], Set 5: { auto (5) }
//
// Note that, since |NGGridBlockTrackCollection|'s ranges are assured to span a
// single repeater and to not cross any grid item's boundary in the respective
// dimension, tracks within a set are "commutative" and can be sized evenly.
class CORE_EXPORT NGGridSet {
public:
NGGridSet(wtf_size_t track_count, bool is_collapsed);
NGGridSet(wtf_size_t track_count, const GridTrackSize& track_size);
wtf_size_t TrackCount() const { return track_count_; }
const GridTrackSize& TrackSize() const { return track_size_; }
private:
wtf_size_t track_count_;
GridTrackSize track_size_;
};
class CORE_EXPORT NGGridLayoutAlgorithmTrackCollection
: public NGGridTrackCollectionBase {
public:
struct Range {
// Copies fields that are the same as in |GridBlockTrackCollection::Range|.
Range(const NGGridBlockTrackCollection::Range& block_track_range,
wtf_size_t starting_set_index);
wtf_size_t starting_track_number;
wtf_size_t track_count;
wtf_size_t starting_set_index;
wtf_size_t set_count;
bool is_collapsed;
};
class CORE_EXPORT SetIterator {
public:
SetIterator(NGGridLayoutAlgorithmTrackCollection* collection,
wtf_size_t begin_set_index,
wtf_size_t end_set_index);
bool IsAtEnd() const;
bool MoveToNextSet();
NGGridSet& CurrentSet() const;
private:
NGGridLayoutAlgorithmTrackCollection* collection_;
wtf_size_t current_set_index_;
wtf_size_t end_set_index_;
};
explicit NGGridLayoutAlgorithmTrackCollection(
const NGGridBlockTrackCollection& block_track_collection);
// Returns a reference to the set located at position |set_index|.
NGGridSet& SetAt(wtf_size_t set_index);
// Returns an iterator for all the sets contained within the |range_index|-th
// range of the collection. Note that this iterator can alter any set's data.
SetIterator IteratorForRange(wtf_size_t range_index);
protected:
// NGGridTrackCollectionBase overrides.
wtf_size_t RangeTrackNumber(wtf_size_t range_index) const override;
wtf_size_t RangeTrackCount(wtf_size_t range_index) const override;
bool IsRangeCollapsed(wtf_size_t range_index) const override;
wtf_size_t RangeCount() const override;
private:
void AppendTrackRange(
const NGGridBlockTrackCollection::Range& block_track_range,
const NGGridTrackList& specified_track_list);
// Returns the number of sets in the collection.
wtf_size_t SetCount() const;
Vector<Range> ranges_;
// A vector of every set element that compose the entire collection's ranges;
// track definitions from the same set are stored in consecutive positions,
// preserving the order in which the definitions appear in their range.
Vector<NGGridSet> sets_;
};
} // namespace blink } // namespace blink
WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::NGGridTrackRepeater) WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(blink::NGGridTrackRepeater)
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
namespace blink { namespace blink {
namespace { namespace {
#define EXPECT_RANGE(expected_start, expected_count, iterator) \ #define EXPECT_RANGE(expected_start, expected_count, iterator) \
EXPECT_EQ(expected_count, iterator.RepeatCount()); \ EXPECT_EQ(expected_count, iterator.RepeatCount()); \
EXPECT_EQ(expected_start, iterator.RangeTrackStart()); \ EXPECT_EQ(expected_start, iterator.RangeTrackStart()); \
...@@ -20,6 +21,10 @@ namespace { ...@@ -20,6 +21,10 @@ namespace {
EXPECT_EQ(expected_count, iterator.RepeatCount()); \ EXPECT_EQ(expected_count, iterator.RepeatCount()); \
EXPECT_EQ(expected_start + expected_count - 1, iterator.RangeTrackEnd()); \ EXPECT_EQ(expected_start + expected_count - 1, iterator.RangeTrackEnd()); \
EXPECT_TRUE(iterator.IsRangeCollapsed()); EXPECT_TRUE(iterator.IsRangeCollapsed());
#define EXPECT_SET(expected_size, expected_count, iterator) \
EXPECT_EQ(expected_size, iterator.CurrentSet().TrackSize()); \
EXPECT_EQ(expected_count, iterator.CurrentSet().TrackCount());
class NGGridTrackCollectionBaseTest : public NGGridTrackCollectionBase { class NGGridTrackCollectionBaseTest : public NGGridTrackCollectionBase {
public: public:
struct TestTrackRange { struct TestTrackRange {
...@@ -53,7 +58,12 @@ class NGGridTrackCollectionBaseTest : public NGGridTrackCollectionBase { ...@@ -53,7 +58,12 @@ class NGGridTrackCollectionBaseTest : public NGGridTrackCollectionBase {
Vector<TestTrackRange> ranges_; Vector<TestTrackRange> ranges_;
}; };
using NGGridTrackCollectionTest = NGLayoutTest; class NGGridTrackCollectionTest : public NGLayoutTest {
protected:
Vector<GridTrackSize> CreateTrackSizes(wtf_size_t track_count) {
return {track_count, GridTrackSize(Length::Auto())};
}
};
TEST_F(NGGridTrackCollectionTest, TestRangeIndexFromTrackNumber) { TEST_F(NGGridTrackCollectionTest, TestRangeIndexFromTrackNumber) {
// Small case. // Small case.
...@@ -87,7 +97,7 @@ TEST_F(NGGridTrackCollectionTest, TestRangeIndexFromTrackNumber) { ...@@ -87,7 +97,7 @@ TEST_F(NGGridTrackCollectionTest, TestRangeIndexFromTrackNumber) {
} }
TEST_F(NGGridTrackCollectionTest, TestRangeRepeatIteratorMoveNext) { TEST_F(NGGridTrackCollectionTest, TestRangeRepeatIteratorMoveNext) {
// [1-3] [4-13] [14 -18] // [0-2] [3-12] [13-17]
NGGridTrackCollectionBaseTest track_collection({3u, 10u, 5u}); NGGridTrackCollectionBaseTest track_collection({3u, 10u, 5u});
EXPECT_EQ(0u, track_collection.RangeIndexFromTrackNumber(0u)); EXPECT_EQ(0u, track_collection.RangeIndexFromTrackNumber(0u));
...@@ -120,52 +130,59 @@ TEST_F(NGGridTrackCollectionTest, TestNGGridTrackList) { ...@@ -120,52 +130,59 @@ TEST_F(NGGridTrackCollectionTest, TestNGGridTrackList) {
ASSERT_EQ(0u, track_list.RepeaterCount()); ASSERT_EQ(0u, track_list.RepeaterCount());
EXPECT_FALSE(track_list.HasAutoRepeater()); EXPECT_FALSE(track_list.HasAutoRepeater());
EXPECT_TRUE(track_list.AddRepeater(0, 2, 4)); EXPECT_TRUE(track_list.AddRepeater(CreateTrackSizes(2), 4));
ASSERT_EQ(1u, track_list.RepeaterCount()); ASSERT_EQ(1u, track_list.RepeaterCount());
EXPECT_EQ(8u, track_list.TotalTrackCount()); EXPECT_EQ(8u, track_list.TotalTrackCount());
EXPECT_EQ(4u, track_list.RepeatCount(0, 77)); EXPECT_EQ(4u, track_list.RepeatCount(0, 4));
EXPECT_EQ(2u, track_list.RepeatSize(0)); EXPECT_EQ(2u, track_list.RepeatSize(0));
EXPECT_FALSE(track_list.HasAutoRepeater()); EXPECT_FALSE(track_list.HasAutoRepeater());
EXPECT_TRUE(track_list.AddAutoRepeater(2, 3, AutoRepeatType::kAutoFill)); // Can't add an empty repeater to a list.
ASSERT_EQ(2u, track_list.RepeaterCount()); EXPECT_FALSE(track_list.AddAutoRepeater(CreateTrackSizes(0),
EXPECT_EQ(11u, track_list.TotalTrackCount()); AutoRepeatType::kAutoFit));
EXPECT_EQ(77u, track_list.RepeatCount(1, 77)); EXPECT_FALSE(track_list.AddRepeater(CreateTrackSizes(3), 0));
EXPECT_EQ(3u, track_list.RepeatSize(1)); ASSERT_EQ(1u, track_list.RepeaterCount());
EXPECT_TRUE(track_list.HasAutoRepeater());
// Can't add more than one auto repeater to a list.
EXPECT_FALSE(track_list.AddAutoRepeater(5, 3, AutoRepeatType::kAutoFill));
EXPECT_TRUE(track_list.AddRepeater( EXPECT_TRUE(track_list.AddRepeater(
5, NGGridTrackCollectionBase::kMaxRangeIndex - 20, 1)); CreateTrackSizes(1), NGGridTrackCollectionBase::kMaxRangeIndex - 20));
ASSERT_EQ(3u, track_list.RepeaterCount()); ASSERT_EQ(2u, track_list.RepeaterCount());
EXPECT_EQ(NGGridTrackCollectionBase::kMaxRangeIndex - 9, EXPECT_EQ(NGGridTrackCollectionBase::kMaxRangeIndex - 12u,
track_list.TotalTrackCount()); track_list.TotalTrackCount());
EXPECT_EQ(1u, track_list.RepeatCount(2, 77)); EXPECT_EQ(NGGridTrackCollectionBase::kMaxRangeIndex - 20u,
EXPECT_EQ(NGGridTrackCollectionBase::kMaxRangeIndex - 20, track_list.RepeatCount(1, 4));
track_list.RepeatSize(2)); EXPECT_EQ(1u, track_list.RepeatSize(1));
EXPECT_FALSE(track_list.HasAutoRepeater());
// Try to add a repeater that would overflow the total track count. // Try to add a repeater that would overflow the total track count.
EXPECT_FALSE(track_list.AddRepeater( EXPECT_FALSE(track_list.AddRepeater(CreateTrackSizes(5), 7));
NGGridTrackCollectionBase::kMaxRangeIndex - 15u, 3, 10)); EXPECT_FALSE(track_list.AddRepeater(CreateTrackSizes(7), 5));
EXPECT_FALSE(track_list.AddAutoRepeater(CreateTrackSizes(31),
AutoRepeatType::kAutoFill));
ASSERT_EQ(2u, track_list.RepeaterCount());
EXPECT_TRUE(track_list.AddAutoRepeater(CreateTrackSizes(3),
AutoRepeatType::kAutoFit));
ASSERT_EQ(3u, track_list.RepeaterCount()); ASSERT_EQ(3u, track_list.RepeaterCount());
EXPECT_EQ(NGGridTrackCollectionBase::kMaxRangeIndex - 9u,
track_list.TotalTrackCount());
EXPECT_EQ(4u, track_list.RepeatCount(2, 4));
EXPECT_EQ(3u, track_list.RepeatSize(2));
EXPECT_TRUE(track_list.HasAutoRepeater());
// Try to add a repeater that would overflow the track size in a repeater. // Can't add more than one auto repeater to a list.
EXPECT_FALSE( EXPECT_FALSE(track_list.AddAutoRepeater(CreateTrackSizes(3),
track_list.AddRepeater(NGGridTrackCollectionBase::kMaxRangeIndex - 15u, AutoRepeatType::kAutoFill));
NGGridTrackCollectionBase::kMaxRangeIndex, 10));
ASSERT_EQ(3u, track_list.RepeaterCount()); ASSERT_EQ(3u, track_list.RepeaterCount());
} }
TEST_F(NGGridTrackCollectionTest, TestNGGridBlockTrackCollection) { TEST_F(NGGridTrackCollectionTest, TestNGGridBlockTrackCollection) {
NGGridTrackList specified_tracks; NGGridTrackList specified_tracks;
ASSERT_TRUE(specified_tracks.AddRepeater(1, 2, 4)); ASSERT_TRUE(specified_tracks.AddRepeater(CreateTrackSizes(2), 4));
ASSERT_TRUE( ASSERT_TRUE(specified_tracks.AddAutoRepeater(CreateTrackSizes(3),
specified_tracks.AddAutoRepeater(3, 3, AutoRepeatType::kAutoFill)); AutoRepeatType::kAutoFill));
ASSERT_EQ(2u, specified_tracks.RepeaterCount()); ASSERT_EQ(2u, specified_tracks.RepeaterCount());
NGGridBlockTrackCollection block_collection; NGGridBlockTrackCollection block_collection;
block_collection.SetSpecifiedTracks(specified_tracks, 3, NGGridTrackList()); block_collection.SetSpecifiedTracks(specified_tracks, NGGridTrackList(), 3);
block_collection.FinalizeRanges(); block_collection.FinalizeRanges();
NGGridTrackCollectionBase::RangeRepeatIterator iterator(&block_collection, NGGridTrackCollectionBase::RangeRepeatIterator iterator(&block_collection,
...@@ -180,12 +197,13 @@ TEST_F(NGGridTrackCollectionTest, TestNGGridBlockTrackCollection) { ...@@ -180,12 +197,13 @@ TEST_F(NGGridTrackCollectionTest, TestNGGridBlockTrackCollection) {
TEST_F(NGGridTrackCollectionTest, TestNGGridBlockTrackCollectionCollapsed) { TEST_F(NGGridTrackCollectionTest, TestNGGridBlockTrackCollectionCollapsed) {
NGGridTrackList specified_tracks; NGGridTrackList specified_tracks;
ASSERT_TRUE(specified_tracks.AddRepeater(1, 2, 4)); ASSERT_TRUE(specified_tracks.AddRepeater(CreateTrackSizes(2), 4));
ASSERT_TRUE(specified_tracks.AddAutoRepeater(3, 3, AutoRepeatType::kAutoFit)); ASSERT_TRUE(specified_tracks.AddAutoRepeater(CreateTrackSizes(3),
ASSERT_TRUE(specified_tracks.AddRepeater(6, 3, 7)); AutoRepeatType::kAutoFit));
ASSERT_TRUE(specified_tracks.AddRepeater(CreateTrackSizes(3), 7));
ASSERT_EQ(3u, specified_tracks.RepeaterCount()); ASSERT_EQ(3u, specified_tracks.RepeaterCount());
NGGridBlockTrackCollection block_collection; NGGridBlockTrackCollection block_collection;
block_collection.SetSpecifiedTracks(specified_tracks, 3, NGGridTrackList()); block_collection.SetSpecifiedTracks(specified_tracks, NGGridTrackList(), 3);
block_collection.FinalizeRanges(); block_collection.FinalizeRanges();
NGGridTrackCollectionBase::RangeRepeatIterator iterator(&block_collection, NGGridTrackCollectionBase::RangeRepeatIterator iterator(&block_collection,
...@@ -203,16 +221,16 @@ TEST_F(NGGridTrackCollectionTest, TestNGGridBlockTrackCollectionCollapsed) { ...@@ -203,16 +221,16 @@ TEST_F(NGGridTrackCollectionTest, TestNGGridBlockTrackCollectionCollapsed) {
TEST_F(NGGridTrackCollectionTest, TestNGGridBlockTrackCollectionImplicit) { TEST_F(NGGridTrackCollectionTest, TestNGGridBlockTrackCollectionImplicit) {
NGGridTrackList specified_tracks; NGGridTrackList specified_tracks;
ASSERT_TRUE(specified_tracks.AddRepeater(1, 2, 4)); ASSERT_TRUE(specified_tracks.AddRepeater(CreateTrackSizes(2), 4));
ASSERT_TRUE(specified_tracks.AddRepeater(3, 3, 3)); ASSERT_TRUE(specified_tracks.AddRepeater(CreateTrackSizes(3), 3));
ASSERT_TRUE(specified_tracks.AddRepeater(6, 3, 7)); ASSERT_TRUE(specified_tracks.AddRepeater(CreateTrackSizes(3), 7));
ASSERT_EQ(3u, specified_tracks.RepeaterCount()); ASSERT_EQ(3u, specified_tracks.RepeaterCount());
NGGridTrackList implicit_tracks; NGGridTrackList implicit_tracks;
ASSERT_TRUE(implicit_tracks.AddRepeater(1, 8, 2)); ASSERT_TRUE(implicit_tracks.AddRepeater(CreateTrackSizes(8), 2));
NGGridBlockTrackCollection block_collection; NGGridBlockTrackCollection block_collection;
block_collection.SetSpecifiedTracks(specified_tracks, 3, implicit_tracks); block_collection.SetSpecifiedTracks(specified_tracks, implicit_tracks, 3);
block_collection.EnsureTrackCoverage(3, 40); block_collection.EnsureTrackCoverage(3, 40);
block_collection.EnsureTrackCoverage(3, 40); block_collection.EnsureTrackCoverage(3, 40);
block_collection.FinalizeRanges(); block_collection.FinalizeRanges();
...@@ -240,6 +258,243 @@ TEST_F(NGGridTrackCollectionTest, TestNGGridBlockTrackCollectionImplicit) { ...@@ -240,6 +258,243 @@ TEST_F(NGGridTrackCollectionTest, TestNGGridBlockTrackCollectionImplicit) {
EXPECT_FALSE(iterator.MoveToNextRange()); EXPECT_FALSE(iterator.MoveToNextRange());
} }
TEST_F(NGGridTrackCollectionTest,
TestNGGridLayoutAlgorithmTrackCollectionSetIterator) {
Vector<wtf_size_t> set_counts = {2, 5, 3, 11, 13, 7};
NGGridTrackList specified_tracks;
for (wtf_size_t set_count : set_counts)
ASSERT_TRUE(specified_tracks.AddRepeater(CreateTrackSizes(set_count), 1));
ASSERT_EQ(set_counts.size(), specified_tracks.RepeaterCount());
NGGridBlockTrackCollection block_collection;
block_collection.SetSpecifiedTracks(specified_tracks, NGGridTrackList(),
/* auto_repeat_count */ 0);
block_collection.FinalizeRanges();
NGGridLayoutAlgorithmTrackCollection algorithm_collection(block_collection);
wtf_size_t set_count = 0;
wtf_size_t range_count = 0;
NGGridTrackCollectionBase::RangeRepeatIterator range_iterator =
algorithm_collection.RangeIterator();
for (; !range_iterator.IsAtEnd(); ++range_count) {
EXPECT_RANGE(1u + set_count, set_counts[range_count], range_iterator);
wtf_size_t current_set_count = 0;
NGGridLayoutAlgorithmTrackCollection::SetIterator set_iterator =
algorithm_collection.IteratorForRange(range_iterator.RangeIndex());
for (; !set_iterator.IsAtEnd(); ++current_set_count) {
EXPECT_SET(GridTrackSize(Length::Auto()), 1u, set_iterator);
set_iterator.MoveToNextSet();
}
EXPECT_EQ(set_counts[range_count], current_set_count);
set_count += current_set_count;
range_iterator.MoveToNextRange();
}
EXPECT_EQ(set_counts.size(), range_count);
EXPECT_EQ(41u, set_count);
}
TEST_F(NGGridTrackCollectionTest,
TestNGGridLayoutAlgorithmTrackCollectionExplicitTracks) {
// We'll use fixed size tracks to differentiate between them by int value.
NGGridTrackList explicit_tracks;
// repeat(3, 1px 2px 3px)
Vector<GridTrackSize> track_sizes = {GridTrackSize(Length::Fixed(1)),
GridTrackSize(Length::Fixed(2)),
GridTrackSize(Length::Fixed(3))};
ASSERT_TRUE(explicit_tracks.AddRepeater(track_sizes, 3));
// repeat(auto-fit, 4px 5px)
track_sizes = {GridTrackSize(Length::Fixed(4)),
GridTrackSize(Length::Fixed(5))};
ASSERT_TRUE(
explicit_tracks.AddAutoRepeater(track_sizes, AutoRepeatType::kAutoFit));
ASSERT_EQ(2u, explicit_tracks.RepeaterCount());
NGGridBlockTrackCollection block_collection;
block_collection.SetSpecifiedTracks(explicit_tracks, NGGridTrackList(),
/* auto_repeat_count */ 5);
block_collection.EnsureTrackCoverage(3, 4);
block_collection.EnsureTrackCoverage(13, 4);
block_collection.EnsureTrackCoverage(18, 3);
block_collection.EnsureTrackCoverage(23, 5);
block_collection.FinalizeRanges();
NGGridLayoutAlgorithmTrackCollection algorithm_collection(block_collection);
NGGridTrackCollectionBase::RangeRepeatIterator range_iterator =
algorithm_collection.RangeIterator();
EXPECT_RANGE(1u, 2u, range_iterator);
NGGridLayoutAlgorithmTrackCollection::SetIterator set_iterator =
algorithm_collection.IteratorForRange(range_iterator.RangeIndex());
EXPECT_SET(GridTrackSize(Length::Fixed(1)), 1u, set_iterator);
EXPECT_TRUE(set_iterator.MoveToNextSet());
EXPECT_SET(GridTrackSize(Length::Fixed(2)), 1u, set_iterator);
EXPECT_FALSE(set_iterator.MoveToNextSet());
EXPECT_TRUE(range_iterator.MoveToNextRange());
EXPECT_RANGE(3u, 4u, range_iterator);
set_iterator =
algorithm_collection.IteratorForRange(range_iterator.RangeIndex());
EXPECT_SET(GridTrackSize(Length::Fixed(3)), 2u, set_iterator);
EXPECT_TRUE(set_iterator.MoveToNextSet());
EXPECT_SET(GridTrackSize(Length::Fixed(1)), 1u, set_iterator);
EXPECT_TRUE(set_iterator.MoveToNextSet());
EXPECT_SET(GridTrackSize(Length::Fixed(2)), 1u, set_iterator);
EXPECT_FALSE(set_iterator.MoveToNextSet());
EXPECT_TRUE(range_iterator.MoveToNextRange());
EXPECT_RANGE(7u, 3u, range_iterator);
set_iterator =
algorithm_collection.IteratorForRange(range_iterator.RangeIndex());
EXPECT_SET(GridTrackSize(Length::Fixed(1)), 1u, set_iterator);
EXPECT_TRUE(set_iterator.MoveToNextSet());
EXPECT_SET(GridTrackSize(Length::Fixed(2)), 1u, set_iterator);
EXPECT_TRUE(set_iterator.MoveToNextSet());
EXPECT_SET(GridTrackSize(Length::Fixed(3)), 1u, set_iterator);
EXPECT_FALSE(set_iterator.MoveToNextSet());
EXPECT_TRUE(range_iterator.MoveToNextRange());
EXPECT_COLLAPSED_RANGE(10u, 3u, range_iterator);
set_iterator =
algorithm_collection.IteratorForRange(range_iterator.RangeIndex());
EXPECT_SET(GridTrackSize(Length::Fixed(0)), 3u, set_iterator);
EXPECT_FALSE(set_iterator.MoveToNextSet());
EXPECT_TRUE(range_iterator.MoveToNextRange());
EXPECT_RANGE(13u, 4u, range_iterator);
set_iterator =
algorithm_collection.IteratorForRange(range_iterator.RangeIndex());
EXPECT_SET(GridTrackSize(Length::Fixed(5)), 2u, set_iterator);
EXPECT_TRUE(set_iterator.MoveToNextSet());
EXPECT_SET(GridTrackSize(Length::Fixed(4)), 2u, set_iterator);
EXPECT_FALSE(set_iterator.MoveToNextSet());
EXPECT_TRUE(range_iterator.MoveToNextRange());
EXPECT_COLLAPSED_RANGE(17u, 1u, range_iterator);
set_iterator =
algorithm_collection.IteratorForRange(range_iterator.RangeIndex());
EXPECT_SET(GridTrackSize(Length::Fixed(0)), 1u, set_iterator);
EXPECT_FALSE(set_iterator.MoveToNextSet());
EXPECT_TRUE(range_iterator.MoveToNextRange());
EXPECT_RANGE(18u, 2u, range_iterator);
set_iterator =
algorithm_collection.IteratorForRange(range_iterator.RangeIndex());
EXPECT_SET(GridTrackSize(Length::Fixed(4)), 1u, set_iterator);
EXPECT_TRUE(set_iterator.MoveToNextSet());
EXPECT_SET(GridTrackSize(Length::Fixed(5)), 1u, set_iterator);
EXPECT_FALSE(set_iterator.MoveToNextSet());
EXPECT_TRUE(range_iterator.MoveToNextRange());
EXPECT_RANGE(20u, 1u, range_iterator);
set_iterator =
algorithm_collection.IteratorForRange(range_iterator.RangeIndex());
EXPECT_SET(GridTrackSize(Length::Auto()), 1u, set_iterator);
EXPECT_FALSE(set_iterator.MoveToNextSet());
EXPECT_TRUE(range_iterator.MoveToNextRange());
EXPECT_RANGE(21u, 2u, range_iterator);
set_iterator =
algorithm_collection.IteratorForRange(range_iterator.RangeIndex());
EXPECT_SET(GridTrackSize(Length::Auto()), 2u, set_iterator);
EXPECT_FALSE(set_iterator.MoveToNextSet());
EXPECT_TRUE(range_iterator.MoveToNextRange());
EXPECT_RANGE(23u, 5u, range_iterator);
set_iterator =
algorithm_collection.IteratorForRange(range_iterator.RangeIndex());
EXPECT_SET(GridTrackSize(Length::Auto()), 5u, set_iterator);
EXPECT_FALSE(set_iterator.MoveToNextSet());
EXPECT_FALSE(range_iterator.MoveToNextRange());
}
TEST_F(NGGridTrackCollectionTest,
TestNGGridLayoutAlgorithmTrackCollectionImplicitTracks) {
// We'll use fixed size tracks to differentiate between them by int value.
NGGridTrackList explicit_tracks, implicit_tracks;
// Explicit grid: 1px 2px 3px 4px
Vector<GridTrackSize> track_sizes = {
GridTrackSize(Length::Fixed(1)), GridTrackSize(Length::Fixed(2)),
GridTrackSize(Length::Fixed(3)), GridTrackSize(Length::Fixed(4))};
ASSERT_TRUE(explicit_tracks.AddRepeater(track_sizes, 1));
ASSERT_EQ(1u, explicit_tracks.RepeaterCount());
// Implicit grid: 5px 6px 7px
track_sizes = {GridTrackSize(Length::Fixed(5)),
GridTrackSize(Length::Fixed(6)),
GridTrackSize(Length::Fixed(7))};
ASSERT_TRUE(implicit_tracks.AddRepeater(track_sizes, 1));
ASSERT_EQ(1u, implicit_tracks.RepeaterCount());
NGGridBlockTrackCollection block_collection;
block_collection.SetSpecifiedTracks(explicit_tracks, implicit_tracks,
/* auto_repeat_count */ 0);
block_collection.EnsureTrackCoverage(3, 13);
block_collection.EnsureTrackCoverage(24, 2);
block_collection.FinalizeRanges();
NGGridLayoutAlgorithmTrackCollection algorithm_collection(block_collection);
NGGridTrackCollectionBase::RangeRepeatIterator range_iterator =
algorithm_collection.RangeIterator();
EXPECT_RANGE(1u, 2u, range_iterator);
NGGridLayoutAlgorithmTrackCollection::SetIterator set_iterator =
algorithm_collection.IteratorForRange(range_iterator.RangeIndex());
EXPECT_SET(GridTrackSize(Length::Fixed(1)), 1u, set_iterator);
EXPECT_TRUE(set_iterator.MoveToNextSet());
EXPECT_SET(GridTrackSize(Length::Fixed(2)), 1u, set_iterator);
EXPECT_FALSE(set_iterator.MoveToNextSet());
EXPECT_TRUE(range_iterator.MoveToNextRange());
EXPECT_RANGE(3u, 2u, range_iterator);
set_iterator =
algorithm_collection.IteratorForRange(range_iterator.RangeIndex());
EXPECT_SET(GridTrackSize(Length::Fixed(3)), 1u, set_iterator);
EXPECT_TRUE(set_iterator.MoveToNextSet());
EXPECT_SET(GridTrackSize(Length::Fixed(4)), 1u, set_iterator);
EXPECT_FALSE(set_iterator.MoveToNextSet());
EXPECT_TRUE(range_iterator.MoveToNextRange());
EXPECT_RANGE(5u, 11u, range_iterator);
set_iterator =
algorithm_collection.IteratorForRange(range_iterator.RangeIndex());
EXPECT_SET(GridTrackSize(Length::Fixed(5)), 4u, set_iterator);
EXPECT_TRUE(set_iterator.MoveToNextSet());
EXPECT_SET(GridTrackSize(Length::Fixed(6)), 4u, set_iterator);
EXPECT_TRUE(set_iterator.MoveToNextSet());
EXPECT_SET(GridTrackSize(Length::Fixed(7)), 3u, set_iterator);
EXPECT_FALSE(set_iterator.MoveToNextSet());
EXPECT_TRUE(range_iterator.MoveToNextRange());
EXPECT_RANGE(16u, 8u, range_iterator);
set_iterator =
algorithm_collection.IteratorForRange(range_iterator.RangeIndex());
EXPECT_SET(GridTrackSize(Length::Fixed(7)), 3u, set_iterator);
EXPECT_TRUE(set_iterator.MoveToNextSet());
EXPECT_SET(GridTrackSize(Length::Fixed(5)), 3u, set_iterator);
EXPECT_TRUE(set_iterator.MoveToNextSet());
EXPECT_SET(GridTrackSize(Length::Fixed(6)), 2u, set_iterator);
EXPECT_FALSE(set_iterator.MoveToNextSet());
EXPECT_TRUE(range_iterator.MoveToNextRange());
EXPECT_RANGE(24u, 2u, range_iterator);
set_iterator =
algorithm_collection.IteratorForRange(range_iterator.RangeIndex());
EXPECT_SET(GridTrackSize(Length::Fixed(6)), 1u, set_iterator);
EXPECT_TRUE(set_iterator.MoveToNextSet());
EXPECT_SET(GridTrackSize(Length::Fixed(7)), 1u, set_iterator);
EXPECT_FALSE(set_iterator.MoveToNextSet());
EXPECT_FALSE(range_iterator.MoveToNextRange());
}
} // namespace } // namespace
} // namespace blink } // namespace blink
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment