Chromium Code Reviews| 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 = findFrUnitSize(tracks, GridSpan(0, tracks.size() - 1), di rection, 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 = findFrUnitSize(tracks, span, direction , 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 ? logicalWidth() : std::max(LayoutUnit(), computeContentLogicalHeight(MainOrPreferredSize, style( )->logicalHeight(), -1))); | 509 return valueForLength(trackLength, direction == ForColumns ? logicalWidth() : 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::findFrUnitSize(Vector<GridTrack>& tracks, const GridSpan& tra cksSpan, GridTrackSizingDirection direction, LayoutUnit spaceToFill, TrackIndexS et tracksToTreatAsInflexible) const |
| 532 { | 513 { |
| 533 return track1.m_normalizedFlexValue < track2.m_normalizedFlexValue; | 514 if (spaceToFill <= 0) |
| 534 } | 515 return 0; |
| 535 | 516 |
| 536 double LayoutGrid::computeNormalizedFractionBreadth(Vector<GridTrack>& tracks, c onst GridSpan& tracksSpan, GridTrackSizingDirection direction, LayoutUnit spaceT oFill) const | 517 double flexFactorSum = 0; |
| 537 { | 518 LayoutUnit leftOverSpace = spaceToFill; |
| 538 LayoutUnit allocatedSpace; | 519 Vector<size_t> flexibleSizedTracksIndex; |
| 539 Vector<GridTrackForNormalization> tracksForNormalization; | |
| 540 for (const auto& resolvedPosition : tracksSpan) { | 520 for (const auto& resolvedPosition : tracksSpan) { |
| 541 GridTrack& track = tracks[resolvedPosition.toInt()]; | 521 size_t trackIndex = resolvedPosition.toInt(); |
| 542 allocatedSpace += track.baseSize(); | 522 GridTrackSize trackSize = gridTrackSize(direction, trackIndex); |
| 543 | 523 if (!trackSize.maxTrackBreadth().isFlex() || tracksToTreatAsInflexible.c ontains(trackIndex)) { |
| 544 GridTrackSize trackSize = gridTrackSize(direction, resolvedPosition.toIn t()); | 524 leftOverSpace -= tracks[trackIndex].baseSize(); |
| 545 if (!trackSize.maxTrackBreadth().isFlex()) | 525 } else { |
| 546 continue; | 526 flexibleSizedTracksIndex.append(trackIndex); |
| 547 | 527 flexFactorSum += trackSize.maxTrackBreadth().flex(); |
| 548 tracksForNormalization.append(GridTrackForNormalization(track, trackSize .maxTrackBreadth().flex())); | |
| 549 } | |
| 550 | |
| 551 // The function is not called if we don't have <flex> grid tracks | |
| 552 ASSERT(!tracksForNormalization.isEmpty()); | |
| 553 | |
| 554 std::sort(tracksForNormalization.begin(), tracksForNormalization.end(), sort ByGridNormalizedFlexValue); | |
| 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 } | 528 } |
| 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 } | 529 } |
| 577 | 530 |
| 578 // Let flex factor sum be the sum of the flex factors of the flexible tracks . If this value | 531 // 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. | 532 // is less than 1, set it to 1 instead. |
| 580 if (accumulatedFractions < 1) | 533 double hypotheticalFrSize = flexFactorSum > 1 ? leftOverSpace / flexFactorSu m : leftOverSpace.toDouble(); |
| 581 return availableLogicalSpaceIgnoringFractionTracks; | |
| 582 | 534 |
| 583 return availableLogicalSpaceIgnoringFractionTracks / accumulatedFractions; | 535 // If the product of the hypothetical fr size and a flexible track's flex fa ctor is less |
| 536 // than the track's base size, restart this algorithm treating all such trac ks as inflexible | |
| 537 bool succeed = true; | |
| 538 for (size_t trackIndex : flexibleSizedTracksIndex) { | |
| 539 if (hypotheticalFrSize * gridTrackSize(direction, trackIndex).maxTrackBr eadth().flex() < tracks[trackIndex].baseSize().toDouble()) { | |
| 540 tracksToTreatAsInflexible.add(trackIndex); | |
| 541 succeed = false; | |
| 542 } | |
| 543 } | |
| 544 | |
| 545 return succeed ? hypotheticalFrSize : findFrUnitSize(tracks, tracksSpan, dir ection, spaceToFill, tracksToTreatAsInflexible); | |
|
esprehn
2015/09/10 01:03:14
This recursion keeps creating more copies of the s
| |
| 584 } | 546 } |
| 585 | 547 |
| 586 bool LayoutGrid::hasDefiniteLogicalSize(GridTrackSizingDirection direction) cons t | 548 bool LayoutGrid::hasDefiniteLogicalSize(GridTrackSizingDirection direction) cons t |
| 587 { | 549 { |
| 588 return (direction == ForRows) ? hasDefiniteLogicalHeight() : hasDefiniteLogi calWidth(); | 550 return (direction == ForRows) ? hasDefiniteLogicalHeight() : hasDefiniteLogi calWidth(); |
| 589 } | 551 } |
| 590 | 552 |
| 591 GridTrackSize LayoutGrid::gridTrackSize(GridTrackSizingDirection direction, size _t i) const | 553 GridTrackSize LayoutGrid::gridTrackSize(GridTrackSizingDirection direction, size _t i) const |
| 592 { | 554 { |
| 593 bool isForColumns = direction == ForColumns; | 555 bool isForColumns = direction == ForColumns; |
| (...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1923 | 1885 |
| 1924 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); | 1886 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); |
| 1925 } | 1887 } |
| 1926 | 1888 |
| 1927 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset) | 1889 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset) |
| 1928 { | 1890 { |
| 1929 GridPainter(*this).paintChildren(paintInfo, paintOffset); | 1891 GridPainter(*this).paintChildren(paintInfo, paintOffset); |
| 1930 } | 1892 } |
| 1931 | 1893 |
| 1932 } // namespace blink | 1894 } // namespace blink |
| OLD | NEW |