OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2011 Apple Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
135 , distributionOffset(distribution) | 135 , distributionOffset(distribution) |
136 { | 136 { |
137 } | 137 } |
138 | 138 |
139 bool isValid() { return positionOffset >= 0 && distributionOffset >= 0; } | 139 bool isValid() { return positionOffset >= 0 && distributionOffset >= 0; } |
140 | 140 |
141 LayoutUnit positionOffset = -1; | 141 LayoutUnit positionOffset = -1; |
142 LayoutUnit distributionOffset = -1; | 142 LayoutUnit distributionOffset = -1; |
143 }; | 143 }; |
144 | 144 |
145 struct GridTrackForNormalization { | |
146 GridTrackForNormalization(const GridTrack& track, double flex) | |
147 : m_track(&track) | |
148 , m_flex(flex) | |
149 , m_normalizedFlexValue(track.baseSize() / flex) | |
150 { | |
151 } | |
152 | |
153 // Required by std::sort. | |
154 GridTrackForNormalization& operator=(const GridTrackForNormalization& o) | |
155 { | |
156 m_track = o.m_track; | |
157 m_flex = o.m_flex; | |
158 m_normalizedFlexValue = o.m_normalizedFlexValue; | |
159 return *this; | |
160 } | |
161 | |
162 const GridTrack* m_track; | |
163 double m_flex; | |
164 LayoutUnit m_normalizedFlexValue; | |
165 }; | |
166 | |
167 enum TrackSizeRestriction { | 145 enum TrackSizeRestriction { |
168 AllowInfinity, | 146 AllowInfinity, |
169 ForbidInfinity, | 147 ForbidInfinity, |
170 }; | 148 }; |
171 | 149 |
172 class LayoutGrid::GridIterator { | 150 class LayoutGrid::GridIterator { |
173 WTF_MAKE_NONCOPYABLE(GridIterator); | 151 WTF_MAKE_NONCOPYABLE(GridIterator); |
174 public: | 152 public: |
175 // |direction| is the direction that is fixed to |fixedTrackIndex| so e.g | 153 // |direction| is the direction that is fixed to |fixedTrackIndex| so e.g |
176 // GridIterator(m_grid, ForColumns, 1) will walk over the rows of the 2nd co lumn. | 154 // GridIterator(m_grid, ForColumns, 1) will walk over the rows of the 2nd co lumn. |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
389 LayoutUnit scrollbarWidth = intrinsicScrollbarLogicalWidth(); | 367 LayoutUnit scrollbarWidth = intrinsicScrollbarLogicalWidth(); |
390 minLogicalWidth += scrollbarWidth; | 368 minLogicalWidth += scrollbarWidth; |
391 maxLogicalWidth += scrollbarWidth; | 369 maxLogicalWidth += scrollbarWidth; |
392 } | 370 } |
393 | 371 |
394 bool LayoutGrid::gridElementIsShrinkToFit() | 372 bool LayoutGrid::gridElementIsShrinkToFit() |
395 { | 373 { |
396 return isFloatingOrOutOfFlowPositioned(); | 374 return isFloatingOrOutOfFlowPositioned(); |
397 } | 375 } |
398 | 376 |
377 static inline double normalizedFlexFraction(const GridTrack& track, double flexF actor) | |
378 { | |
379 return flexFactor > 1 ? track.baseSize() / flexFactor : track.baseSize().toD ouble(); | |
380 } | |
381 | |
399 void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi on, GridSizingData& sizingData, LayoutUnit& freeSpace) | 382 void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi on, GridSizingData& sizingData, LayoutUnit& freeSpace) |
400 { | 383 { |
401 const LayoutUnit initialFreeSpace = freeSpace; | 384 const LayoutUnit initialFreeSpace = freeSpace; |
402 Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.columnTra cks : sizingData.rowTracks; | 385 Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.columnTra cks : sizingData.rowTracks; |
403 Vector<size_t> flexibleSizedTracksIndex; | 386 Vector<size_t> flexibleSizedTracksIndex; |
404 sizingData.contentSizedTracksIndex.shrink(0); | 387 sizingData.contentSizedTracksIndex.shrink(0); |
405 | 388 |
406 // 1. Initialize per Grid track variables. | 389 // 1. Initialize per Grid track variables. |
407 for (size_t i = 0; i < tracks.size(); ++i) { | 390 for (size_t i = 0; i < tracks.size(); ++i) { |
408 GridTrack& track = tracks[i]; | 391 GridTrack& track = tracks[i]; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
449 track->setBaseSize(track->plannedSize()); | 432 track->setBaseSize(track->plannedSize()); |
450 } else { | 433 } else { |
451 for (auto& track : tracks) | 434 for (auto& track : tracks) |
452 track.setBaseSize(track.growthLimit()); | 435 track.setBaseSize(track.growthLimit()); |
453 } | 436 } |
454 | 437 |
455 if (flexibleSizedTracksIndex.isEmpty()) | 438 if (flexibleSizedTracksIndex.isEmpty()) |
456 return; | 439 return; |
457 | 440 |
458 // 4. Grow all Grid tracks having a fraction as the MaxTrackSizingFunction. | 441 // 4. Grow all Grid tracks having a fraction as the MaxTrackSizingFunction. |
459 double normalizedFractionBreadth = 0; | 442 double flexFraction = 0; |
460 if (!hasUndefinedRemainingSpace) { | 443 if (!hasUndefinedRemainingSpace) { |
461 normalizedFractionBreadth = computeNormalizedFractionBreadth(tracks, Gri dSpan(0, tracks.size() - 1), direction, initialFreeSpace); | 444 flexFraction = findFlexFactorUnitSize(tracks, GridSpan(0, tracks.size() - 1), direction, initialFreeSpace); |
462 } else { | 445 } else { |
463 for (const auto& trackIndex : flexibleSizedTracksIndex) { | 446 for (const auto& trackIndex : flexibleSizedTracksIndex) |
464 GridTrackSize trackSize = gridTrackSize(direction, trackIndex); | 447 flexFraction = std::max(flexFraction, normalizedFlexFraction(tracks[ trackIndex], gridTrackSize(direction, trackIndex).maxTrackBreadth().flex())); |
465 normalizedFractionBreadth = std::max(normalizedFractionBreadth, trac ks[trackIndex].baseSize() / trackSize.maxTrackBreadth().flex()); | |
466 } | |
467 | 448 |
468 for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) { | 449 for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) { |
469 GridIterator iterator(m_grid, direction, flexibleSizedTracksIndex[i] ); | 450 GridIterator iterator(m_grid, direction, flexibleSizedTracksIndex[i] ); |
470 while (LayoutBox* gridItem = iterator.nextGridItem()) { | 451 while (LayoutBox* gridItem = iterator.nextGridItem()) { |
471 const GridCoordinate coordinate = cachedGridCoordinate(*gridItem ); | 452 const GridCoordinate coordinate = cachedGridCoordinate(*gridItem ); |
472 const GridSpan span = (direction == ForColumns) ? coordinate.col umns : coordinate.rows; | 453 const GridSpan span = (direction == ForColumns) ? coordinate.col umns : coordinate.rows; |
473 | 454 |
474 // Do not include already processed items. | 455 // Do not include already processed items. |
475 if (i > 0 && span.resolvedInitialPosition.toInt() <= flexibleSiz edTracksIndex[i - 1]) | 456 if (i > 0 && span.resolvedInitialPosition.toInt() <= flexibleSiz edTracksIndex[i - 1]) |
476 continue; | 457 continue; |
477 | 458 |
478 double itemNormalizedFlexBreadth = computeNormalizedFractionBrea dth(tracks, span, direction, maxContentForChild(*gridItem, direction, sizingData .columnTracks)); | 459 double itemFlexFraction = findFlexFactorUnitSize(tracks, span, d irection, maxContentForChild(*gridItem, direction, sizingData.columnTracks)); |
479 normalizedFractionBreadth = std::max(normalizedFractionBreadth, itemNormalizedFlexBreadth); | 460 flexFraction = std::max(flexFraction, itemFlexFraction); |
480 } | 461 } |
481 } | 462 } |
482 } | 463 } |
483 | 464 |
484 for (const auto& trackIndex : flexibleSizedTracksIndex) { | 465 for (const auto& trackIndex : flexibleSizedTracksIndex) { |
485 GridTrackSize trackSize = gridTrackSize(direction, trackIndex); | 466 GridTrackSize trackSize = gridTrackSize(direction, trackIndex); |
486 | 467 |
487 LayoutUnit baseSize = std::max<LayoutUnit>(tracks[trackIndex].baseSize() , normalizedFractionBreadth * trackSize.maxTrackBreadth().flex()); | 468 LayoutUnit baseSize = std::max<LayoutUnit>(tracks[trackIndex].baseSize() , flexFraction * trackSize.maxTrackBreadth().flex()); |
488 tracks[trackIndex].setBaseSize(baseSize); | 469 tracks[trackIndex].setBaseSize(baseSize); |
489 freeSpace -= baseSize; | 470 freeSpace -= baseSize; |
490 } | 471 } |
491 | 472 |
492 // FIXME: Should ASSERT flexible tracks exhaust the freeSpace ? (see issue 7 39613002). | 473 // FIXME: Should ASSERT flexible tracks exhaust the freeSpace ? (see issue 7 39613002). |
493 } | 474 } |
494 | 475 |
495 LayoutUnit LayoutGrid::computeUsedBreadthOfMinLength(GridTrackSizingDirection di rection, const GridLength& gridLength) const | 476 LayoutUnit LayoutGrid::computeUsedBreadthOfMinLength(GridTrackSizingDirection di rection, const GridLength& gridLength) const |
496 { | 477 { |
497 if (gridLength.isFlex()) | 478 if (gridLength.isFlex()) |
(...skipping 23 matching lines...) Expand all Loading... | |
521 return infinity; | 502 return infinity; |
522 } | 503 } |
523 | 504 |
524 LayoutUnit LayoutGrid::computeUsedBreadthOfSpecifiedLength(GridTrackSizingDirect ion direction, const Length& trackLength) const | 505 LayoutUnit LayoutGrid::computeUsedBreadthOfSpecifiedLength(GridTrackSizingDirect ion direction, const Length& trackLength) const |
525 { | 506 { |
526 ASSERT(trackLength.isSpecified()); | 507 ASSERT(trackLength.isSpecified()); |
527 // FIXME: The -1 here should be replaced by whatever the intrinsic height of the grid is. | 508 // FIXME: The -1 here should be replaced by whatever the intrinsic height of the grid is. |
528 return valueForLength(trackLength, direction == ForColumns ? contentLogicalW idth() : std::max(LayoutUnit(), computeContentLogicalHeight(MainOrPreferredSize, style()->logicalHeight(), -1))); | 509 return valueForLength(trackLength, direction == ForColumns ? contentLogicalW idth() : std::max(LayoutUnit(), computeContentLogicalHeight(MainOrPreferredSize, style()->logicalHeight(), -1))); |
529 } | 510 } |
530 | 511 |
531 static bool sortByGridNormalizedFlexValue(const GridTrackForNormalization& track 1, const GridTrackForNormalization& track2) | 512 double LayoutGrid::computeFlexFactorUnitSize(const Vector<GridTrack>& tracks, Gr idTrackSizingDirection direction, double flexFactorSum, double leftOverSpace, co nst Vector<size_t, 8>& flexibleTracks, PassOwnPtr<TrackIndexSet> tracksToTreatAs Inflexible) const |
svillar
2015/09/23 14:57:15
I don't think you need to use specify the initial
| |
532 { | 513 { |
533 return track1.m_normalizedFlexValue < track2.m_normalizedFlexValue; | 514 // Let flex factor sum be the sum of the flex factors of the flexible tracks . If this value |
515 // is less than 1, set it to 1 instead. | |
516 double hypotheticalFactorUnitSize = flexFactorSum > 1 ? leftOverSpace / flex FactorSum : leftOverSpace; | |
svillar
2015/09/23 14:57:15
Although perhaps slightly less efficient, I think
jfernandez
2015/09/24 08:16:36
I think I'll change the comment so it explains why
| |
517 | |
518 // product of the hypothetical "flex factor unit" and any flexible track's " flex factor" must be grater than such track's "base size". | |
519 OwnPtr<TrackIndexSet> additionalTacksToTreatAsInflexible = tracksToTreatAsIn flexible; | |
svillar
2015/09/23 14:57:15
nit: additionalTracks
jfernandez
2015/09/24 08:16:36
Done.
| |
520 bool validFlexFactorUnit = true; | |
521 for (auto index : flexibleTracks) { | |
522 if (additionalTacksToTreatAsInflexible && additionalTacksToTreatAsInflex ible->contains(index)) | |
523 continue; | |
524 double baseSize = tracks[index].baseSize(); | |
525 double flexFactor = gridTrackSize(direction, index).maxTrackBreadth().fl ex(); | |
526 // treating all such tracks as inflexible. | |
527 if (hypotheticalFactorUnitSize * flexFactor < baseSize) { | |
528 leftOverSpace -= baseSize; | |
529 flexFactorSum -= flexFactor; | |
530 if (!additionalTacksToTreatAsInflexible) | |
531 additionalTacksToTreatAsInflexible = adoptPtr(new TrackIndexSet( )); | |
532 additionalTacksToTreatAsInflexible->add(index); | |
533 validFlexFactorUnit = false; | |
534 } | |
535 } | |
536 return validFlexFactorUnit ? hypotheticalFactorUnitSize : computeFlexFactorU nitSize(tracks, direction, flexFactorSum, leftOverSpace, flexibleTracks, additio nalTacksToTreatAsInflexible.release()); | |
svillar
2015/09/23 14:57:15
I know this is nitpicking but I'd prefer this to b
jfernandez
2015/09/24 08:16:36
Done.
| |
534 } | 537 } |
535 | 538 |
536 double LayoutGrid::computeNormalizedFractionBreadth(Vector<GridTrack>& tracks, c onst GridSpan& tracksSpan, GridTrackSizingDirection direction, LayoutUnit spaceT oFill) const | 539 double LayoutGrid::findFlexFactorUnitSize(const Vector<GridTrack>& tracks, const GridSpan& tracksSpan, GridTrackSizingDirection direction, LayoutUnit spaceToFil l) const |
537 { | 540 { |
538 LayoutUnit allocatedSpace; | 541 if (spaceToFill <= 0) |
539 Vector<GridTrackForNormalization> tracksForNormalization; | 542 return 0; |
543 | |
544 double flexFactorSum = 0; | |
545 double leftOverSpace = spaceToFill; | |
svillar
2015/09/23 14:57:15
Why are you using doubles here? Although the flex
jfernandez
2015/09/24 08:16:36
Well, some operators doesn't allow to mix LayoutUn
| |
546 Vector<size_t, 8> flexibleTracks; | |
540 for (const auto& resolvedPosition : tracksSpan) { | 547 for (const auto& resolvedPosition : tracksSpan) { |
541 GridTrack& track = tracks[resolvedPosition.toInt()]; | 548 size_t trackIndex = resolvedPosition.toInt(); |
542 allocatedSpace += track.baseSize(); | 549 GridTrackSize trackSize = gridTrackSize(direction, trackIndex); |
543 | 550 double baseSize = tracks[trackIndex].baseSize(); |
544 GridTrackSize trackSize = gridTrackSize(direction, resolvedPosition.toIn t()); | 551 if (!trackSize.maxTrackBreadth().isFlex()) { |
545 if (!trackSize.maxTrackBreadth().isFlex()) | 552 leftOverSpace -= baseSize; |
546 continue; | 553 } else { |
547 | 554 double flexFactor = trackSize.maxTrackBreadth().flex(); |
548 tracksForNormalization.append(GridTrackForNormalization(track, trackSize .maxTrackBreadth().flex())); | 555 flexibleTracks.append(trackIndex); |
556 flexFactorSum += flexFactor; | |
557 } | |
549 } | 558 } |
550 | 559 |
551 // The function is not called if we don't have <flex> grid tracks | 560 // The function is not called if we don't have <flex> grid tracks |
552 ASSERT(!tracksForNormalization.isEmpty()); | 561 ASSERT(!flexibleTracks.isEmpty()); |
553 | 562 |
554 std::sort(tracksForNormalization.begin(), tracksForNormalization.end(), sort ByGridNormalizedFlexValue); | 563 return computeFlexFactorUnitSize(tracks, direction, flexFactorSum, leftOverS pace, flexibleTracks); |
555 | |
556 // These values work together: as we walk over our grid tracks, we increase fractionValueBasedOnGridItemsRatio | |
557 // to match a grid track's usedBreadth to <flex> ratio until the total fract ions sized grid tracks wouldn't | |
558 // fit into availableLogicalSpaceIgnoringFractionTracks. | |
559 double accumulatedFractions = 0; | |
560 LayoutUnit fractionValueBasedOnGridItemsRatio = 0; | |
561 LayoutUnit availableLogicalSpaceIgnoringFractionTracks = spaceToFill - alloc atedSpace; | |
562 | |
563 for (const auto& track : tracksForNormalization) { | |
564 if (track.m_normalizedFlexValue > fractionValueBasedOnGridItemsRatio) { | |
565 // If the normalized flex value (we ordered |tracksForNormalization| by increasing normalized flex value) | |
566 // will make us overflow our container, then stop. We have the previ ous step's ratio is the best fit. | |
567 if (track.m_normalizedFlexValue * accumulatedFractions > availableLo gicalSpaceIgnoringFractionTracks) | |
568 break; | |
569 | |
570 fractionValueBasedOnGridItemsRatio = track.m_normalizedFlexValue; | |
571 } | |
572 | |
573 accumulatedFractions += track.m_flex; | |
574 // This item was processed so we re-add its used breadth to the availabl e space to accurately count the remaining space. | |
575 availableLogicalSpaceIgnoringFractionTracks += track.m_track->baseSize() ; | |
576 } | |
577 | |
578 // Let flex factor sum be the sum of the flex factors of the flexible tracks . If this value | |
579 // is less than 1, set it to 1 instead. | |
580 if (accumulatedFractions < 1) | |
581 return availableLogicalSpaceIgnoringFractionTracks; | |
582 | |
583 return availableLogicalSpaceIgnoringFractionTracks / accumulatedFractions; | |
584 } | 564 } |
585 | 565 |
586 bool LayoutGrid::hasDefiniteLogicalSize(GridTrackSizingDirection direction) cons t | 566 bool LayoutGrid::hasDefiniteLogicalSize(GridTrackSizingDirection direction) cons t |
587 { | 567 { |
588 return (direction == ForRows) ? hasDefiniteLogicalHeight() : hasDefiniteLogi calWidth(); | 568 return (direction == ForRows) ? hasDefiniteLogicalHeight() : hasDefiniteLogi calWidth(); |
589 } | 569 } |
590 | 570 |
591 GridTrackSize LayoutGrid::gridTrackSize(GridTrackSizingDirection direction, size _t i) const | 571 GridTrackSize LayoutGrid::gridTrackSize(GridTrackSizingDirection direction, size _t i) const |
592 { | 572 { |
593 bool isForColumns = direction == ForColumns; | 573 bool isForColumns = direction == ForColumns; |
(...skipping 1332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1926 | 1906 |
1927 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); | 1907 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); |
1928 } | 1908 } |
1929 | 1909 |
1930 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset) | 1910 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset) |
1931 { | 1911 { |
1932 GridPainter(*this).paintChildren(paintInfo, paintOffset); | 1912 GridPainter(*this).paintChildren(paintInfo, paintOffset); |
1933 } | 1913 } |
1934 | 1914 |
1935 } // namespace blink | 1915 } // namespace blink |
OLD | NEW |