Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(190)

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutGrid.cpp

Issue 1317643005: [css-grid] Fix track sizing algo w/ size restrictions and intrinsic sizes (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebased stuff. Added some more tests Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 GridTrackSizingDirection m_direction; 223 GridTrackSizingDirection m_direction;
224 size_t m_rowIndex; 224 size_t m_rowIndex;
225 size_t m_columnIndex; 225 size_t m_columnIndex;
226 size_t m_childIndex; 226 size_t m_childIndex;
227 }; 227 };
228 228
229 struct LayoutGrid::GridSizingData { 229 struct LayoutGrid::GridSizingData {
230 WTF_MAKE_NONCOPYABLE(GridSizingData); 230 WTF_MAKE_NONCOPYABLE(GridSizingData);
231 STACK_ALLOCATED(); 231 STACK_ALLOCATED();
232 public: 232 public:
233 GridSizingData(size_t gridColumnCount, size_t gridRowCount, const LayoutUnit & freeSpaceForColumns, const LayoutUnit& freeSpaceForRows) 233 GridSizingData(size_t gridColumnCount, size_t gridRowCount)
234 : columnTracks(gridColumnCount) 234 : columnTracks(gridColumnCount)
235 , rowTracks(gridRowCount) 235 , rowTracks(gridRowCount)
236 , freeSpaceForColumns(freeSpaceForColumns)
237 , freeSpaceForRows(freeSpaceForRows)
238 { 236 {
239 } 237 }
240 238
241 Vector<GridTrack> columnTracks; 239 Vector<GridTrack> columnTracks;
242 Vector<GridTrack> rowTracks; 240 Vector<GridTrack> rowTracks;
243 Vector<size_t> contentSizedTracksIndex; 241 Vector<size_t> contentSizedTracksIndex;
244 242
245 // Performance optimization: hold onto these Vectors until the end of Layout to avoid repeated malloc / free. 243 // Performance optimization: hold onto these Vectors until the end of Layout to avoid repeated malloc / free.
246 Vector<GridTrack*> filteredTracks; 244 Vector<GridTrack*> filteredTracks;
247 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan; 245 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan;
248 Vector<GridTrack*> growBeyondGrowthLimitsTracks; 246 Vector<GridTrack*> growBeyondGrowthLimitsTracks;
249 247
250 LayoutUnit& freeSpaceForDirection(GridTrackSizingDirection direction) { retu rn direction == ForColumns ? freeSpaceForColumns : freeSpaceForRows; } 248 LayoutUnit& freeSpaceForDirection(GridTrackSizingDirection direction) { retu rn direction == ForColumns ? freeSpaceForColumns : freeSpaceForRows; }
251 249
252 private: 250 private:
253 LayoutUnit freeSpaceForColumns; 251 LayoutUnit freeSpaceForColumns { };
254 LayoutUnit freeSpaceForRows; 252 LayoutUnit freeSpaceForRows { };
255 }; 253 };
256 254
257 struct GridItemsSpanGroupRange { 255 struct GridItemsSpanGroupRange {
258 Vector<GridItemWithSpan>::iterator rangeStart; 256 Vector<GridItemWithSpan>::iterator rangeStart;
259 Vector<GridItemWithSpan>::iterator rangeEnd; 257 Vector<GridItemWithSpan>::iterator rangeEnd;
260 }; 258 };
261 259
262 LayoutGrid::LayoutGrid(Element* element) 260 LayoutGrid::LayoutGrid(Element* element)
263 : LayoutBlock(element) 261 : LayoutBlock(element)
264 , m_gridIsDirty(true) 262 , m_gridIsDirty(true)
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 return oldStyle.gridTemplateColumns().size() != styleRef().gridTemplateColum ns().size() 307 return oldStyle.gridTemplateColumns().size() != styleRef().gridTemplateColum ns().size()
310 || oldStyle.gridTemplateRows().size() != styleRef().gridTemplateRows().s ize(); 308 || oldStyle.gridTemplateRows().size() != styleRef().gridTemplateRows().s ize();
311 } 309 }
312 310
313 bool LayoutGrid::namedGridLinesDefinitionDidChange(const ComputedStyle& oldStyle ) const 311 bool LayoutGrid::namedGridLinesDefinitionDidChange(const ComputedStyle& oldStyle ) const
314 { 312 {
315 return oldStyle.namedGridRowLines() != styleRef().namedGridRowLines() 313 return oldStyle.namedGridRowLines() != styleRef().namedGridRowLines()
316 || oldStyle.namedGridColumnLines() != styleRef().namedGridColumnLines(); 314 || oldStyle.namedGridColumnLines() != styleRef().namedGridColumnLines();
317 } 315 }
318 316
317 LayoutUnit LayoutGrid::computeTrackBasedLogicalHeight(const GridSizingData& sizi ngData) const
318 {
319 LayoutUnit logicalHeight = borderAndPaddingLogicalHeight() + scrollbarLogica lHeight();
320
321 for (const auto& row : sizingData.rowTracks)
322 logicalHeight += row.baseSize();
323
324 logicalHeight += guttersSize(ForRows, sizingData.rowTracks.size());
325
326 return logicalHeight;
327 }
328
329 void LayoutGrid::computeTrackSizesForDirection(GridTrackSizingDirection directio n, GridSizingData& sizingData, LayoutUnit freeSpace)
330 {
331 if (freeSpace != -1) {
332 LayoutUnit totalGuttersSize = guttersSize(direction, direction == ForRow s ? gridRowCount() : gridColumnCount());
333 freeSpace = std::max<LayoutUnit>(0, freeSpace - totalGuttersSize);
334 }
335 sizingData.freeSpaceForDirection(direction) = freeSpace;
336
337 LayoutUnit baseSizes, growthLimits;
338 computeUsedBreadthOfGridTracks(direction, sizingData, baseSizes, growthLimit s);
339 ASSERT(tracksAreWiderThanMinTrackBreadth(direction, sizingData));
340 }
341
319 void LayoutGrid::layoutBlock(bool relayoutChildren) 342 void LayoutGrid::layoutBlock(bool relayoutChildren)
320 { 343 {
321 ASSERT(needsLayout()); 344 ASSERT(needsLayout());
322 345
323 if (!relayoutChildren && simplifiedLayout()) 346 if (!relayoutChildren && simplifiedLayout())
324 return; 347 return;
325 348
326 // FIXME: Much of this method is boiler plate that matches LayoutBox::layout Block and Layout*FlexibleBox::layoutBlock.
327 // It would be nice to refactor some of the duplicate code.
328 { 349 {
329 // LayoutState needs this deliberate scope to pop before updating scroll information (which 350 // LayoutState needs this deliberate scope to pop before updating scroll information (which
330 // may trigger relayout). 351 // may trigger relayout).
331 LayoutState state(*this, locationOffset()); 352 LayoutState state(*this, locationOffset());
332 353
333 LayoutSize previousSize = size(); 354 LayoutSize previousSize = size();
334 355
335 setLogicalHeight(0);
336 updateLogicalWidth(); 356 updateLogicalWidth();
357 bool logicalHeightWasIndefinite = computeContentLogicalHeight(MainOrPref erredSize, style()->logicalHeight(), -1) == -1;
337 358
338 TextAutosizer::LayoutScope textAutosizerLayoutScope(this); 359 TextAutosizer::LayoutScope textAutosizerLayoutScope(this);
339 360
340 layoutGridItems(); 361 placeItemsOnGrid();
362
363 GridSizingData sizingData(gridColumnCount(), gridRowCount());
364
365 // At this point the logical width is always definite as the above call to updateLogicalWidth()
366 // properly resolves intrinsic sizes. We cannot do the same for heights though because many code
367 // paths inside updateLogicalHeight() require a previous call to setLogi calHeight() to resolve
368 // heights properly (like for positioned items for example).
369 computeTrackSizesForDirection(ForColumns, sizingData, availableLogicalWi dth());
370
371 if (logicalHeightWasIndefinite)
372 computeIntrinsicLogicalHeight(sizingData, borderAndPaddingLogicalHei ght());
373 else
374 computeTrackSizesForDirection(ForRows, sizingData, availableLogicalH eight(ExcludeMarginBorderPadding));
375 setLogicalHeight(computeTrackBasedLogicalHeight(sizingData));
341 376
342 LayoutUnit oldClientAfterEdge = clientLogicalBottom(); 377 LayoutUnit oldClientAfterEdge = clientLogicalBottom();
343 updateLogicalHeight(); 378 updateLogicalHeight();
344 379
380 // The above call might have changed the grid's logical height depending on min|max height restrictions.
381 // Update the sizes of the rows whose size depends on the logical height (also on definite|indefinite sizes).
382 if (logicalHeightWasIndefinite)
383 computeTrackSizesForDirection(ForRows, sizingData, logicalHeight());
384
385 applyStretchAlignmentToTracksIfNeeded(ForColumns, sizingData);
386 applyStretchAlignmentToTracksIfNeeded(ForRows, sizingData);
387
388 layoutGridItems(sizingData);
389
345 if (size() != previousSize) 390 if (size() != previousSize)
346 relayoutChildren = true; 391 relayoutChildren = true;
347 392
348 layoutPositionedObjects(relayoutChildren || isDocumentElement()); 393 layoutPositionedObjects(relayoutChildren || isDocumentElement());
349 394
350 computeOverflow(oldClientAfterEdge); 395 computeOverflow(oldClientAfterEdge);
351 } 396 }
352 397
353 updateLayerTransformAfterLayout(); 398 updateLayerTransformAfterLayout();
354 updateScrollInfoAfterLayout(); 399 updateScrollInfoAfterLayout();
355 400
356 clearNeedsLayout(); 401 clearNeedsLayout();
357 } 402 }
358 403
359 LayoutUnit LayoutGrid::guttersSize(GridTrackSizingDirection direction, size_t sp an) const 404 LayoutUnit LayoutGrid::guttersSize(GridTrackSizingDirection direction, size_t sp an) const
360 { 405 {
361 ASSERT(span >= 1); 406 ASSERT(span >= 1);
362 407
363 if (span == 1) 408 if (span == 1)
364 return 0; 409 return 0;
365 410
366 const Length& trackGap = direction == ForColumns ? styleRef().gridColumnGap( ) : styleRef().gridRowGap(); 411 const Length& trackGap = direction == ForColumns ? styleRef().gridColumnGap( ) : styleRef().gridRowGap();
367 return valueForLength(trackGap, 0) * (span - 1); 412 return valueForLength(trackGap, 0) * (span - 1);
368 } 413 }
369 414
370 void LayoutGrid::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, Layo utUnit& maxLogicalWidth) const 415 void LayoutGrid::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, Layo utUnit& maxLogicalWidth) const
371 { 416 {
372 const_cast<LayoutGrid*>(this)->placeItemsOnGrid(); 417 const_cast<LayoutGrid*>(this)->placeItemsOnGrid();
373 418
374 GridSizingData sizingData(gridColumnCount(), gridRowCount(), 0, 0); 419 GridSizingData sizingData(gridColumnCount(), gridRowCount());
375 const_cast<LayoutGrid*>(this)->computeUsedBreadthOfGridTracks(ForColumns, si zingData); 420 sizingData.freeSpaceForDirection(ForColumns) = -1;
376 421 const_cast<LayoutGrid*>(this)->computeUsedBreadthOfGridTracks(ForColumns, si zingData, minLogicalWidth, maxLogicalWidth);
377 for (const auto& column : sizingData.columnTracks) {
378 const LayoutUnit& minTrackBreadth = column.baseSize();
379 const LayoutUnit& maxTrackBreadth = column.growthLimit();
380
381 minLogicalWidth += minTrackBreadth;
382 maxLogicalWidth += maxTrackBreadth;
383 }
384 422
385 LayoutUnit totalGuttersSize = guttersSize(ForColumns, sizingData.columnTrack s.size()); 423 LayoutUnit totalGuttersSize = guttersSize(ForColumns, sizingData.columnTrack s.size());
386 minLogicalWidth += totalGuttersSize; 424 minLogicalWidth += totalGuttersSize;
387 maxLogicalWidth += totalGuttersSize; 425 maxLogicalWidth += totalGuttersSize;
388 426
389 LayoutUnit scrollbarWidth = intrinsicScrollbarLogicalWidth(); 427 LayoutUnit scrollbarWidth = intrinsicScrollbarLogicalWidth();
390 minLogicalWidth += scrollbarWidth; 428 minLogicalWidth += scrollbarWidth;
391 maxLogicalWidth += scrollbarWidth; 429 maxLogicalWidth += scrollbarWidth;
392 } 430 }
393 431
394 bool LayoutGrid::gridElementIsShrinkToFit() 432 void LayoutGrid::computeIntrinsicLogicalHeight(GridSizingData& sizingData, Layou tUnit borderAndPadding)
395 { 433 {
396 return isFloatingOrOutOfFlowPositioned(); 434 ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, sizingData));
435 sizingData.freeSpaceForDirection(ForRows) = -1;
436 computeUsedBreadthOfGridTracks(ForRows, sizingData, m_minContentHeight, m_ma xContentHeight);
437
438 LayoutUnit totalGuttersSize = guttersSize(ForRows, gridRowCount());
439 m_minContentHeight += totalGuttersSize;
440 m_maxContentHeight += totalGuttersSize;
441
442 // Grid container should have the minimum height of a line if it's editable. That does not affect track sizing though.
443 if (hasLineIfEmpty()) {
444 m_minContentHeight = std::max(m_minContentHeight, minimumLogicalHeightFo rEmptyLine());
445 m_maxContentHeight = std::max(m_maxContentHeight, m_minContentHeight);
446 }
447 ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, sizingData));
448 }
449
450 LayoutUnit LayoutGrid::computeIntrinsicLogicalContentHeightUsing(const Length& l ogicalHeightLength, LayoutUnit intrinsicContentHeight, LayoutUnit borderAndPaddi ng) const
451 {
452 if (logicalHeightLength.isMinContent())
453 return m_minContentHeight;
454
455 if (logicalHeightLength.isMaxContent())
456 return m_maxContentHeight;
457
458 if (logicalHeightLength.isFitContent()) {
459 LayoutUnit fillAvailableExtent = containingBlock()->availableLogicalHeig ht(ExcludeMarginBorderPadding);
460 return std::min<LayoutUnit>(m_maxContentHeight, std::max<LayoutUnit>(m_m inContentHeight, fillAvailableExtent));
461 }
462
463 if (logicalHeightLength.isFillAvailable())
464 return containingBlock()->availableLogicalHeight(ExcludeMarginBorderPadd ing) - borderAndPadding;
465 ASSERT_NOT_REACHED();
466 return 0;
397 } 467 }
398 468
399 static inline double normalizedFlexFraction(const GridTrack& track, double flexF actor) 469 static inline double normalizedFlexFraction(const GridTrack& track, double flexF actor)
400 { 470 {
401 return track.baseSize() / std::max<double>(1, flexFactor); 471 return track.baseSize() / std::max<double>(1, flexFactor);
402 } 472 }
403 473
404 void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi on, GridSizingData& sizingData) 474 void LayoutGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection directi on, GridSizingData& sizingData, LayoutUnit& baseSizesWithoutMaximization, Layout Unit& growthLimitsWithoutMaximization)
405 { 475 {
406 LayoutUnit& freeSpace = sizingData.freeSpaceForDirection(direction); 476 LayoutUnit& freeSpace = sizingData.freeSpaceForDirection(direction);
407 const LayoutUnit initialFreeSpace = freeSpace; 477 const LayoutUnit initialFreeSpace = freeSpace;
408 Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.columnTra cks : sizingData.rowTracks; 478 Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.columnTra cks : sizingData.rowTracks;
409 Vector<size_t> flexibleSizedTracksIndex; 479 Vector<size_t> flexibleSizedTracksIndex;
410 sizingData.contentSizedTracksIndex.shrink(0); 480 sizingData.contentSizedTracksIndex.shrink(0);
411 481
412 const LayoutUnit maxSize = direction == ForColumns ? contentLogicalWidth() : std::max(LayoutUnit(), computeContentLogicalHeight(MainOrPreferredSize, style() ->logicalHeight(), -1)); 482 const LayoutUnit maxSize = std::max(LayoutUnit(), initialFreeSpace);
413 // 1. Initialize per Grid track variables. 483 // 1. Initialize per Grid track variables.
414 for (size_t i = 0; i < tracks.size(); ++i) { 484 for (size_t i = 0; i < tracks.size(); ++i) {
415 GridTrack& track = tracks[i]; 485 GridTrack& track = tracks[i];
416 GridTrackSize trackSize = gridTrackSize(direction, i); 486 GridTrackSize trackSize = gridTrackSize(direction, i);
417 const GridLength& minTrackBreadth = trackSize.minTrackBreadth(); 487 const GridLength& minTrackBreadth = trackSize.minTrackBreadth();
418 const GridLength& maxTrackBreadth = trackSize.maxTrackBreadth(); 488 const GridLength& maxTrackBreadth = trackSize.maxTrackBreadth();
419 489
420 track.setBaseSize(computeUsedBreadthOfMinLength(minTrackBreadth, maxSize )); 490 track.setBaseSize(computeUsedBreadthOfMinLength(minTrackBreadth, maxSize ));
421 track.setGrowthLimit(computeUsedBreadthOfMaxLength(maxTrackBreadth, trac k.baseSize(), maxSize)); 491 track.setGrowthLimit(computeUsedBreadthOfMaxLength(maxTrackBreadth, trac k.baseSize(), maxSize));
422 track.setInfinitelyGrowable(false); 492 track.setInfinitelyGrowable(false);
423 493
424 if (trackSize.isContentSized()) 494 if (trackSize.isContentSized())
425 sizingData.contentSizedTracksIndex.append(i); 495 sizingData.contentSizedTracksIndex.append(i);
426 if (trackSize.maxTrackBreadth().isFlex()) 496 if (trackSize.maxTrackBreadth().isFlex())
427 flexibleSizedTracksIndex.append(i); 497 flexibleSizedTracksIndex.append(i);
428 } 498 }
429 499
430 // 2. Resolve content-based TrackSizingFunctions. 500 // 2. Resolve content-based TrackSizingFunctions.
431 if (!sizingData.contentSizedTracksIndex.isEmpty()) 501 if (!sizingData.contentSizedTracksIndex.isEmpty())
432 resolveContentBasedTrackSizingFunctions(direction, sizingData); 502 resolveContentBasedTrackSizingFunctions(direction, sizingData);
433 503
504 baseSizesWithoutMaximization = growthLimitsWithoutMaximization = 0;
505
434 for (const auto& track: tracks) { 506 for (const auto& track: tracks) {
435 ASSERT(!track.infiniteGrowthPotential()); 507 ASSERT(!track.infiniteGrowthPotential());
436 freeSpace -= track.baseSize(); 508 baseSizesWithoutMaximization += track.baseSize();
509 growthLimitsWithoutMaximization += track.growthLimit();
437 } 510 }
511 freeSpace = initialFreeSpace - baseSizesWithoutMaximization;
438 512
439 const bool hasUndefinedRemainingSpace = (direction == ForRows) ? style()->lo gicalHeight().isAuto() : gridElementIsShrinkToFit(); 513 const bool hasDefiniteFreeSpace = initialFreeSpace != -1;
440 514 if (hasDefiniteFreeSpace && freeSpace <= 0)
441 if (!hasUndefinedRemainingSpace && freeSpace <= 0)
442 return; 515 return;
443 516
444 // 3. Grow all Grid tracks in GridTracks from their baseSize up to their gro wthLimit value until freeSpace is exhausted. 517 // 3. Grow all Grid tracks in GridTracks from their baseSize up to their gro wthLimit value until freeSpace is exhausted.
445 const size_t tracksSize = tracks.size(); 518 const size_t tracksSize = tracks.size();
446 if (!hasUndefinedRemainingSpace) { 519 if (hasDefiniteFreeSpace) {
447 Vector<GridTrack*> tracksForDistribution(tracksSize); 520 Vector<GridTrack*> tracksForDistribution(tracksSize);
448 for (size_t i = 0; i < tracksSize; ++i) { 521 for (size_t i = 0; i < tracksSize; ++i) {
449 tracksForDistribution[i] = tracks.data() + i; 522 tracksForDistribution[i] = tracks.data() + i;
450 tracksForDistribution[i]->setPlannedSize(tracksForDistribution[i]->b aseSize()); 523 tracksForDistribution[i]->setPlannedSize(tracksForDistribution[i]->b aseSize());
451 } 524 }
452 525
453 distributeSpaceToTracks<MaximizeTracks>(tracksForDistribution, nullptr, sizingData, freeSpace); 526 distributeSpaceToTracks<MaximizeTracks>(tracksForDistribution, nullptr, sizingData, freeSpace);
454 527
455 for (auto* track : tracksForDistribution) 528 for (auto* track : tracksForDistribution)
456 track->setBaseSize(track->plannedSize()); 529 track->setBaseSize(track->plannedSize());
457 } else { 530 } else {
458 for (auto& track : tracks) 531 for (auto& track : tracks)
459 track.setBaseSize(track.growthLimit()); 532 track.setBaseSize(track.growthLimit());
460 } 533 }
461 534
462 if (flexibleSizedTracksIndex.isEmpty()) 535 if (flexibleSizedTracksIndex.isEmpty())
463 return; 536 return;
464 537
465 // 4. Grow all Grid tracks having a fraction as the MaxTrackSizingFunction. 538 // 4. Grow all Grid tracks having a fraction as the MaxTrackSizingFunction.
466 double flexFraction = 0; 539 double flexFraction = 0;
467 if (!hasUndefinedRemainingSpace) { 540 if (hasDefiniteFreeSpace) {
468 flexFraction = findFlexFactorUnitSize(tracks, GridSpan(0, tracks.size() - 1), direction, initialFreeSpace); 541 flexFraction = findFlexFactorUnitSize(tracks, GridSpan(0, tracks.size() - 1), direction, initialFreeSpace);
469 } else { 542 } else {
470 for (const auto& trackIndex : flexibleSizedTracksIndex) 543 for (const auto& trackIndex : flexibleSizedTracksIndex)
471 flexFraction = std::max(flexFraction, normalizedFlexFraction(tracks[ trackIndex], gridTrackSize(direction, trackIndex).maxTrackBreadth().flex())); 544 flexFraction = std::max(flexFraction, normalizedFlexFraction(tracks[ trackIndex], gridTrackSize(direction, trackIndex).maxTrackBreadth().flex()));
472 545
473 for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) { 546 for (size_t i = 0; i < flexibleSizedTracksIndex.size(); ++i) {
474 GridIterator iterator(m_grid, direction, flexibleSizedTracksIndex[i] ); 547 GridIterator iterator(m_grid, direction, flexibleSizedTracksIndex[i] );
475 while (LayoutBox* gridItem = iterator.nextGridItem()) { 548 while (LayoutBox* gridItem = iterator.nextGridItem()) {
476 const GridCoordinate coordinate = cachedGridCoordinate(*gridItem ); 549 const GridCoordinate coordinate = cachedGridCoordinate(*gridItem );
477 const GridSpan span = (direction == ForColumns) ? coordinate.col umns : coordinate.rows; 550 const GridSpan span = (direction == ForColumns) ? coordinate.col umns : coordinate.rows;
478 551
479 // Do not include already processed items. 552 // Do not include already processed items.
480 if (i > 0 && span.resolvedInitialPosition.toInt() <= flexibleSiz edTracksIndex[i - 1]) 553 if (i > 0 && span.resolvedInitialPosition.toInt() <= flexibleSiz edTracksIndex[i - 1])
481 continue; 554 continue;
482 555
483 flexFraction = std::max(flexFraction, findFlexFactorUnitSize(tra cks, span, direction, maxContentForChild(*gridItem, direction, sizingData.column Tracks))); 556 flexFraction = std::max(flexFraction, findFlexFactorUnitSize(tra cks, span, direction, maxContentForChild(*gridItem, direction, sizingData.column Tracks)));
484 } 557 }
485 } 558 }
486 } 559 }
487 560
488 for (const auto& trackIndex : flexibleSizedTracksIndex) { 561 for (const auto& trackIndex : flexibleSizedTracksIndex) {
489 GridTrackSize trackSize = gridTrackSize(direction, trackIndex); 562 GridTrackSize trackSize = gridTrackSize(direction, trackIndex);
490 563
491 LayoutUnit oldBaseSize = tracks[trackIndex].baseSize(); 564 LayoutUnit oldBaseSize = tracks[trackIndex].baseSize();
492 LayoutUnit baseSize = std::max<LayoutUnit>(oldBaseSize, flexFraction * t rackSize.maxTrackBreadth().flex()); 565 LayoutUnit baseSize = std::max<LayoutUnit>(oldBaseSize, flexFraction * t rackSize.maxTrackBreadth().flex());
493 if (LayoutUnit increment = baseSize - oldBaseSize) { 566 if (LayoutUnit increment = baseSize - oldBaseSize) {
494 tracks[trackIndex].setBaseSize(baseSize); 567 tracks[trackIndex].setBaseSize(baseSize);
495 freeSpace -= increment; 568 freeSpace -= increment;
569
570 baseSizesWithoutMaximization += increment;
571 growthLimitsWithoutMaximization += increment;
496 } 572 }
497 } 573 }
498
499 // FIXME: Should ASSERT flexible tracks exhaust the freeSpace ? (see issue 7 39613002).
500 } 574 }
501 575
502 LayoutUnit LayoutGrid::computeUsedBreadthOfMinLength(const GridLength& gridLengt h, LayoutUnit maxSize) const 576 LayoutUnit LayoutGrid::computeUsedBreadthOfMinLength(const GridLength& gridLengt h, LayoutUnit maxSize) const
503 { 577 {
504 if (gridLength.isFlex()) 578 if (gridLength.isFlex())
505 return 0; 579 return 0;
506 580
507 const Length& trackLength = gridLength.length(); 581 const Length& trackLength = gridLength.length();
508 if (trackLength.isSpecified()) 582 if (trackLength.isSpecified())
509 return valueForLength(trackLength, maxSize); 583 return valueForLength(trackLength, maxSize);
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 track->growSizeDuringDistribution(growthShare); 1086 track->growSizeDuringDistribution(growthShare);
1013 availableLogicalSpace -= growthShare; 1087 availableLogicalSpace -= growthShare;
1014 } 1088 }
1015 } 1089 }
1016 1090
1017 for (auto* track : tracks) 1091 for (auto* track : tracks)
1018 track->setPlannedSize(track->plannedSize() == infinity ? track->sizeDuri ngDistribution() : std::max(track->plannedSize(), track->sizeDuringDistribution( ))); 1092 track->setPlannedSize(track->plannedSize() == infinity ? track->sizeDuri ngDistribution() : std::max(track->plannedSize(), track->sizeDuringDistribution( )));
1019 } 1093 }
1020 1094
1021 #if ENABLE(ASSERT) 1095 #if ENABLE(ASSERT)
1022 bool LayoutGrid::tracksAreWiderThanMinTrackBreadth(GridTrackSizingDirection dire ction, const Vector<GridTrack>& tracks) 1096 bool LayoutGrid::tracksAreWiderThanMinTrackBreadth(GridTrackSizingDirection dire ction, GridSizingData& sizingData)
1023 { 1097 {
1024 const LayoutUnit maxSize = direction == ForColumns ? contentLogicalWidth() : std::max(LayoutUnit(), computeContentLogicalHeight(MainOrPreferredSize, style() ->logicalHeight(), -1)); 1098 const Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.col umnTracks : sizingData.rowTracks;
1099 LayoutUnit& maxSize = sizingData.freeSpaceForDirection(direction);
1025 for (size_t i = 0; i < tracks.size(); ++i) { 1100 for (size_t i = 0; i < tracks.size(); ++i) {
1026 GridTrackSize trackSize = gridTrackSize(direction, i); 1101 GridTrackSize trackSize = gridTrackSize(direction, i);
1027 const GridLength& minTrackBreadth = trackSize.minTrackBreadth(); 1102 const GridLength& minTrackBreadth = trackSize.minTrackBreadth();
1028 if (computeUsedBreadthOfMinLength(minTrackBreadth, maxSize) > tracks[i]. baseSize()) 1103 if (computeUsedBreadthOfMinLength(minTrackBreadth, maxSize) > tracks[i]. baseSize())
1029 return false; 1104 return false;
1030 } 1105 }
1031 return true; 1106 return true;
1032 } 1107 }
1033 #endif 1108 #endif
1034 1109
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
1303 1378
1304 LayoutUnit sizeToIncrease = availableSpace / numberOfAutoSizedTracks; 1379 LayoutUnit sizeToIncrease = availableSpace / numberOfAutoSizedTracks;
1305 for (const auto& trackIndex : autoSizedTracksIndex) { 1380 for (const auto& trackIndex : autoSizedTracksIndex) {
1306 GridTrack* track = tracks.data() + trackIndex; 1381 GridTrack* track = tracks.data() + trackIndex;
1307 LayoutUnit baseSize = track->baseSize() + sizeToIncrease; 1382 LayoutUnit baseSize = track->baseSize() + sizeToIncrease;
1308 track->setBaseSize(baseSize); 1383 track->setBaseSize(baseSize);
1309 } 1384 }
1310 availableSpace = 0; 1385 availableSpace = 0;
1311 } 1386 }
1312 1387
1313 void LayoutGrid::layoutGridItems() 1388 void LayoutGrid::layoutGridItems(GridSizingData& sizingData)
1314 { 1389 {
1315 placeItemsOnGrid();
1316
1317 LayoutUnit availableSpaceForColumns = availableLogicalWidth();
1318 LayoutUnit availableSpaceForRows = availableLogicalHeight(IncludeMarginBorde rPadding);
1319
1320 // Remove space consumed by gutters from the available logical space.
1321 availableSpaceForColumns -= guttersSize(ForColumns, gridColumnCount());
1322 availableSpaceForRows -= guttersSize(ForRows, gridRowCount());
1323
1324 GridSizingData sizingData(gridColumnCount(), gridRowCount(), availableSpaceF orColumns, availableSpaceForRows);
1325 computeUsedBreadthOfGridTracks(ForColumns, sizingData);
1326 ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, sizingData.columnTracks ));
1327 computeUsedBreadthOfGridTracks(ForRows, sizingData);
1328 ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, sizingData.rowTracks));
1329
1330 applyStretchAlignmentToTracksIfNeeded(ForColumns, sizingData);
1331 applyStretchAlignmentToTracksIfNeeded(ForRows, sizingData);
1332
1333 populateGridPositions(sizingData); 1390 populateGridPositions(sizingData);
1334 m_gridItemsOverflowingGridArea.resize(0); 1391 m_gridItemsOverflowingGridArea.resize(0);
1335 1392
1336 for (LayoutBox* child = firstChildBox(); child; child = child->nextSiblingBo x()) { 1393 for (LayoutBox* child = firstChildBox(); child; child = child->nextSiblingBo x()) {
1337 if (child->isOutOfFlowPositioned()) { 1394 if (child->isOutOfFlowPositioned()) {
1338 prepareChildForPositionedLayout(*child); 1395 prepareChildForPositionedLayout(*child);
1339 continue; 1396 continue;
1340 } 1397 }
1341 1398
1342 // Because the grid area cannot be styled, we don't need to adjust 1399 // Because the grid area cannot be styled, we don't need to adjust
(...skipping 28 matching lines...) Expand all
1371 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT racks.size()); 1428 ASSERT(coordinate.rows.resolvedInitialPosition.toInt() < sizingData.rowT racks.size());
1372 #endif 1429 #endif
1373 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData)); 1430 child->setLogicalLocation(findChildLogicalPosition(*child, sizingData));
1374 1431
1375 // Keep track of children overflowing their grid area as we might need t o paint them even if the grid-area is 1432 // Keep track of children overflowing their grid area as we might need t o paint them even if the grid-area is
1376 // not visible 1433 // not visible
1377 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight 1434 if (child->logicalHeight() > overrideContainingBlockContentLogicalHeight
1378 || child->logicalWidth() > overrideContainingBlockContentLogicalWidt h) 1435 || child->logicalWidth() > overrideContainingBlockContentLogicalWidt h)
1379 m_gridItemsOverflowingGridArea.append(child); 1436 m_gridItemsOverflowingGridArea.append(child);
1380 } 1437 }
1381
1382 LayoutUnit height = borderAndPaddingLogicalHeight() + scrollbarLogicalHeight ();
1383 for (const auto& row : sizingData.rowTracks)
1384 height += row.baseSize();
1385
1386 height += guttersSize(ForRows, sizingData.rowTracks.size());
1387
1388 if (hasLineIfEmpty())
1389 height = std::max(height, minimumLogicalHeightForEmptyLine());
1390
1391 // Min / max logical height is handled by the call to updateLogicalHeight in layoutBlock.
1392 setLogicalHeight(height);
1393 } 1438 }
1394 1439
1395 void LayoutGrid::prepareChildForPositionedLayout(LayoutBox& child) 1440 void LayoutGrid::prepareChildForPositionedLayout(LayoutBox& child)
1396 { 1441 {
1397 ASSERT(child.isOutOfFlowPositioned()); 1442 ASSERT(child.isOutOfFlowPositioned());
1398 child.containingBlock()->insertPositionedObject(&child); 1443 child.containingBlock()->insertPositionedObject(&child);
1399 1444
1400 PaintLayer* childLayer = child.layer(); 1445 PaintLayer* childLayer = child.layer();
1401 childLayer->setStaticInlinePosition(borderAndPaddingStart()); 1446 childLayer->setStaticInlinePosition(borderAndPaddingStart());
1402 childLayer->setStaticBlockPosition(borderAndPaddingBefore()); 1447 childLayer->setStaticBlockPosition(borderAndPaddingBefore());
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after
2031 2076
2032 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child)); 2077 return LayoutPoint(rowAxisOffset, columnAxisOffsetForChild(child));
2033 } 2078 }
2034 2079
2035 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset) const 2080 void LayoutGrid::paintChildren(const PaintInfo& paintInfo, const LayoutPoint& pa intOffset) const
2036 { 2081 {
2037 GridPainter(*this).paintChildren(paintInfo, paintOffset); 2082 GridPainter(*this).paintChildren(paintInfo, paintOffset);
2038 } 2083 }
2039 2084
2040 } // namespace blink 2085 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698