|
Lines 66-71
public:
a/Source/WebCore/rendering/RenderGrid.cpp_sec1
|
| 66 |
LayoutUnit m_maxBreadth; |
66 |
LayoutUnit m_maxBreadth; |
| 67 |
}; |
67 |
}; |
| 68 |
|
68 |
|
|
|
69 |
struct GridTrackForNormalization { |
| 70 |
GridTrackForNormalization(const GridTrack& track, double flex) |
| 71 |
: m_track(&track) |
| 72 |
, m_flex(flex) |
| 73 |
, m_normalizedFlexValue(track.m_usedBreadth / flex) |
| 74 |
{ |
| 75 |
} |
| 76 |
|
| 77 |
// Required by std::sort. |
| 78 |
GridTrackForNormalization operator=(const GridTrackForNormalization& o) |
| 79 |
{ |
| 80 |
m_track = o.m_track; |
| 81 |
m_flex = o.m_flex; |
| 82 |
m_normalizedFlexValue = o.m_normalizedFlexValue; |
| 83 |
return *this; |
| 84 |
} |
| 85 |
|
| 86 |
const GridTrack* m_track; |
| 87 |
double m_flex; |
| 88 |
LayoutUnit m_normalizedFlexValue; |
| 89 |
}; |
| 90 |
|
| 69 |
class RenderGrid::GridIterator { |
91 |
class RenderGrid::GridIterator { |
| 70 |
WTF_MAKE_NONCOPYABLE(GridIterator); |
92 |
WTF_MAKE_NONCOPYABLE(GridIterator); |
| 71 |
public: |
93 |
public: |
|
Lines 228-235
void RenderGrid::computePreferredLogicalWidths()
a/Source/WebCore/rendering/RenderGrid.cpp_sec2
|
| 228 |
setPreferredLogicalWidthsDirty(false); |
250 |
setPreferredLogicalWidthsDirty(false); |
| 229 |
} |
251 |
} |
| 230 |
|
252 |
|
| 231 |
LayoutUnit RenderGrid::computePreferredTrackWidth(const Length& length, size_t trackIndex) const |
253 |
LayoutUnit RenderGrid::computePreferredTrackWidth(const GridLength& gridLength, size_t trackIndex) const |
| 232 |
{ |
254 |
{ |
|
|
255 |
if (gridLength.isFlex()) |
| 256 |
return 0; |
| 257 |
|
| 258 |
const Length& length = gridLength.length(); |
| 259 |
|
| 233 |
if (length.isFixed()) { |
260 |
if (length.isFixed()) { |
| 234 |
// Grid areas don't have borders, margins or paddings so we don't need to account for them. |
261 |
// Grid areas don't have borders, margins or paddings so we don't need to account for them. |
| 235 |
return length.intValue(); |
262 |
return length.intValue(); |
|
Lines 267-277
void RenderGrid::computedUsedBreadthOfGridTracks(TrackSizingDirection direction,
a/Source/WebCore/rendering/RenderGrid.cpp_sec3
|
| 267 |
for (size_t i = 0; i < tracks.size(); ++i) { |
294 |
for (size_t i = 0; i < tracks.size(); ++i) { |
| 268 |
GridTrack& track = tracks[i]; |
295 |
GridTrack& track = tracks[i]; |
| 269 |
const GridTrackSize& trackSize = gridTrackSize(direction, i); |
296 |
const GridTrackSize& trackSize = gridTrackSize(direction, i); |
| 270 |
const Length& minTrackBreadth = trackSize.minTrackBreadth(); |
297 |
const GridLength& minTrackBreadth = trackSize.minTrackBreadth(); |
| 271 |
const Length& maxTrackBreadth = trackSize.maxTrackBreadth(); |
298 |
const GridLength& maxTrackBreadth = trackSize.maxTrackBreadth(); |
| 272 |
|
299 |
|
| 273 |
track.m_usedBreadth = computeUsedBreadthOfMinLength(direction, minTrackBreadth); |
300 |
track.m_usedBreadth = computeUsedBreadthOfMinLength(direction, minTrackBreadth); |
| 274 |
track.m_maxBreadth = computeUsedBreadthOfMaxLength(direction, maxTrackBreadth); |
301 |
track.m_maxBreadth = computeUsedBreadthOfMaxLength(direction, maxTrackBreadth, track.m_usedBreadth); |
| 275 |
|
302 |
|
| 276 |
track.m_maxBreadth = std::max(track.m_maxBreadth, track.m_usedBreadth); |
303 |
track.m_maxBreadth = std::max(track.m_maxBreadth, track.m_usedBreadth); |
| 277 |
} |
304 |
} |
|
Lines 288-313
void RenderGrid::computedUsedBreadthOfGridTracks(TrackSizingDirection direction,
a/Source/WebCore/rendering/RenderGrid.cpp_sec4
|
| 288 |
tracksForDistribution[i] = tracks.data() + i; |
315 |
tracksForDistribution[i] = tracks.data() + i; |
| 289 |
|
316 |
|
| 290 |
distributeSpaceToTracks(tracksForDistribution, 0, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth, availableLogicalSpace); |
317 |
distributeSpaceToTracks(tracksForDistribution, 0, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth, availableLogicalSpace); |
|
|
318 |
|
| 319 |
// 4. Grow all Grid tracks having a fraction as the MaxTrackSizingFunction. |
| 320 |
|
| 321 |
// FIXME: Handle the case where RemainingSpace is not defined. |
| 322 |
double normalizedFractionBreadth = computeNormalizedFractionBreadth(tracks, direction, availableLogicalSpace); |
| 323 |
for (size_t i = 0; i < tracksSize; ++i) { |
| 324 |
const GridTrackSize& trackSize = gridTrackSize(direction, i); |
| 325 |
if (!trackSize.maxTrackBreadth().isFlex()) |
| 326 |
continue; |
| 327 |
|
| 328 |
tracks[i].m_usedBreadth = std::max<LayoutUnit>(tracks[i].m_usedBreadth, normalizedFractionBreadth * trackSize.maxTrackBreadth().flex()); |
| 329 |
} |
| 291 |
} |
330 |
} |
| 292 |
|
331 |
|
| 293 |
LayoutUnit RenderGrid::computeUsedBreadthOfMinLength(TrackSizingDirection direction, const Length& trackLength) const |
332 |
LayoutUnit RenderGrid::computeUsedBreadthOfMinLength(TrackSizingDirection direction, const GridLength& gridLength) const |
| 294 |
{ |
333 |
{ |
|
|
334 |
if (gridLength.isFlex()) |
| 335 |
return 0; |
| 336 |
|
| 337 |
const Length& trackLength = gridLength.length(); |
| 338 |
ASSERT(!trackLength.isAuto()); |
| 295 |
if (trackLength.isFixed() || trackLength.isPercent() || trackLength.isViewportPercentage()) |
339 |
if (trackLength.isFixed() || trackLength.isPercent() || trackLength.isViewportPercentage()) |
| 296 |
return computeUsedBreadthOfSpecifiedLength(direction, trackLength); |
340 |
return computeUsedBreadthOfSpecifiedLength(direction, trackLength); |
| 297 |
|
341 |
|
| 298 |
ASSERT(trackLength.isMinContent() || trackLength.isMaxContent() || trackLength.isAuto()); |
342 |
ASSERT(trackLength.isMinContent() || trackLength.isMaxContent()); |
| 299 |
return 0; |
343 |
return 0; |
| 300 |
} |
344 |
} |
| 301 |
|
345 |
|
| 302 |
LayoutUnit RenderGrid::computeUsedBreadthOfMaxLength(TrackSizingDirection direction, const Length& trackLength) const |
346 |
LayoutUnit RenderGrid::computeUsedBreadthOfMaxLength(TrackSizingDirection direction, const GridLength& gridLength, LayoutUnit usedBreadth) const |
| 303 |
{ |
347 |
{ |
|
|
348 |
if (gridLength.isFlex()) |
| 349 |
return usedBreadth; |
| 350 |
|
| 351 |
const Length& trackLength = gridLength.length(); |
| 352 |
ASSERT(!trackLength.isAuto()); |
| 304 |
if (trackLength.isFixed() || trackLength.isPercent() || trackLength.isViewportPercentage()) { |
353 |
if (trackLength.isFixed() || trackLength.isPercent() || trackLength.isViewportPercentage()) { |
| 305 |
LayoutUnit computedBreadth = computeUsedBreadthOfSpecifiedLength(direction, trackLength); |
354 |
LayoutUnit computedBreadth = computeUsedBreadthOfSpecifiedLength(direction, trackLength); |
| 306 |
ASSERT(computedBreadth != infinity); |
355 |
ASSERT(computedBreadth != infinity); |
| 307 |
return computedBreadth; |
356 |
return computedBreadth; |
| 308 |
} |
357 |
} |
| 309 |
|
358 |
|
| 310 |
ASSERT(trackLength.isMinContent() || trackLength.isMaxContent() || trackLength.isAuto()); |
359 |
ASSERT(trackLength.isMinContent() || trackLength.isMaxContent()); |
| 311 |
return infinity; |
360 |
return infinity; |
| 312 |
} |
361 |
} |
| 313 |
|
362 |
|
|
Lines 318-323
LayoutUnit RenderGrid::computeUsedBreadthOfSpecifiedLength(TrackSizingDirection
a/Source/WebCore/rendering/RenderGrid.cpp_sec5
|
| 318 |
return valueForLength(trackLength, direction == ForColumns ? logicalWidth() : computeContentLogicalHeight(style()->logicalHeight()), &view()); |
367 |
return valueForLength(trackLength, direction == ForColumns ? logicalWidth() : computeContentLogicalHeight(style()->logicalHeight()), &view()); |
| 319 |
} |
368 |
} |
| 320 |
|
369 |
|
|
|
370 |
static bool sortByGridNormalizedFlexValue(const GridTrackForNormalization& track1, const GridTrackForNormalization& track2) |
| 371 |
{ |
| 372 |
return track1.m_normalizedFlexValue < track2.m_normalizedFlexValue; |
| 373 |
} |
| 374 |
|
| 375 |
double RenderGrid::computeNormalizedFractionBreadth(Vector<GridTrack>& tracks, TrackSizingDirection direction, LayoutUnit availableLogicalSpace) const |
| 376 |
{ |
| 377 |
// |availableLogicalSpace| already accounts for the used breadths so no need to remove it here. |
| 378 |
|
| 379 |
Vector<GridTrackForNormalization> tracksForNormalization; |
| 380 |
for (size_t i = 0; i < tracks.size(); ++i) { |
| 381 |
const GridTrackSize& trackSize = gridTrackSize(direction, i); |
| 382 |
if (!trackSize.maxTrackBreadth().isFlex()) |
| 383 |
continue; |
| 384 |
|
| 385 |
tracksForNormalization.append(GridTrackForNormalization(tracks[i], trackSize.maxTrackBreadth().flex())); |
| 386 |
} |
| 387 |
|
| 388 |
// FIXME: Ideally we shouldn't come here without any <flex> grid track. |
| 389 |
if (tracksForNormalization.isEmpty()) |
| 390 |
return LayoutUnit(); |
| 391 |
|
| 392 |
std::sort(tracksForNormalization.begin(), tracksForNormalization.end(), sortByGridNormalizedFlexValue); |
| 393 |
|
| 394 |
// These values work together: as we walk over our grid tracks, we increase fractionValueBasedOnGridItemsRatio |
| 395 |
// to match a grid track's usedBreadth to <flex> ratio until the total fractions sized grid tracks wouldn't |
| 396 |
// fit into availableLogicalSpaceIgnoringFractionTracks. |
| 397 |
double accumulatedFractions = 0; |
| 398 |
LayoutUnit fractionValueBasedOnGridItemsRatio = 0; |
| 399 |
LayoutUnit availableLogicalSpaceIgnoringFractionTracks = availableLogicalSpace; |
| 400 |
|
| 401 |
for (size_t i = 0; i < tracksForNormalization.size(); ++i) { |
| 402 |
const GridTrackForNormalization& track = tracksForNormalization[i]; |
| 403 |
if (track.m_normalizedFlexValue > fractionValueBasedOnGridItemsRatio) { |
| 404 |
// If the normalized flex value (we ordered |tracksForNormalization| by increasing normalized flex value) |
| 405 |
// will make us overflow our container, then stop. We have the previous step's ratio is the best fit. |
| 406 |
if (track.m_normalizedFlexValue * accumulatedFractions > availableLogicalSpaceIgnoringFractionTracks) |
| 407 |
break; |
| 408 |
|
| 409 |
fractionValueBasedOnGridItemsRatio = track.m_normalizedFlexValue; |
| 410 |
} |
| 411 |
|
| 412 |
accumulatedFractions += track.m_flex; |
| 413 |
// This item was processed so we re-add its used breadth to the available space to accurately count the remaining space. |
| 414 |
availableLogicalSpaceIgnoringFractionTracks += track.m_track->m_usedBreadth; |
| 415 |
} |
| 416 |
|
| 417 |
return availableLogicalSpaceIgnoringFractionTracks / accumulatedFractions; |
| 418 |
} |
| 419 |
|
| 321 |
const GridTrackSize& RenderGrid::gridTrackSize(TrackSizingDirection direction, size_t i) const |
420 |
const GridTrackSize& RenderGrid::gridTrackSize(TrackSizingDirection direction, size_t i) const |
| 322 |
{ |
421 |
{ |
| 323 |
const Vector<GridTrackSize>& trackStyles = (direction == ForColumns) ? style()->gridColumns() : style()->gridRows(); |
422 |
const Vector<GridTrackSize>& trackStyles = (direction == ForColumns) ? style()->gridColumns() : style()->gridRows(); |
|
Lines 411-417
LayoutUnit RenderGrid::maxContentForChild(RenderBox* child, TrackSizingDirection
a/Source/WebCore/rendering/RenderGrid.cpp_sec6
|
| 411 |
|
510 |
|
| 412 |
void RenderGrid::resolveContentBasedTrackSizingFunctions(TrackSizingDirection direction, Vector<GridTrack>& columnTracks, Vector<GridTrack>& rowTracks, LayoutUnit& availableLogicalSpace) |
511 |
void RenderGrid::resolveContentBasedTrackSizingFunctions(TrackSizingDirection direction, Vector<GridTrack>& columnTracks, Vector<GridTrack>& rowTracks, LayoutUnit& availableLogicalSpace) |
| 413 |
{ |
512 |
{ |
| 414 |
// FIXME: Split the grid tracks once we support fractions (step 1 of the algorithm). |
513 |
// FIXME: Split the grid tracks into groups that doesn't overlap a <flex> grid track. |
| 415 |
|
514 |
|
| 416 |
Vector<GridTrack>& tracks = (direction == ForColumns) ? columnTracks : rowTracks; |
515 |
Vector<GridTrack>& tracks = (direction == ForColumns) ? columnTracks : rowTracks; |
| 417 |
|
516 |
|
|
Lines 474-480
void RenderGrid::distributeSpaceToTracks(Vector<GridTrack*>& tracks, Vector<Grid
a/Source/WebCore/rendering/RenderGrid.cpp_sec7
|
| 474 |
GridTrack& track = *tracks[i]; |
573 |
GridTrack& track = *tracks[i]; |
| 475 |
LayoutUnit availableLogicalSpaceShare = availableLogicalSpace / (tracksSize - i); |
574 |
LayoutUnit availableLogicalSpaceShare = availableLogicalSpace / (tracksSize - i); |
| 476 |
LayoutUnit trackBreadth = (tracks[i]->*trackGetter)(); |
575 |
LayoutUnit trackBreadth = (tracks[i]->*trackGetter)(); |
| 477 |
LayoutUnit growthShare = std::min(availableLogicalSpaceShare, track.m_maxBreadth - trackBreadth); |
576 |
LayoutUnit growthShare = std::max(LayoutUnit(), std::min(availableLogicalSpaceShare, track.m_maxBreadth - trackBreadth)); |
|
|
577 |
// We should never shrink any grid track or else we can't guarantee we abide by our min-sizing function. |
| 478 |
updatedTrackBreadths[i] = trackBreadth + growthShare; |
578 |
updatedTrackBreadths[i] = trackBreadth + growthShare; |
| 479 |
availableLogicalSpace -= growthShare; |
579 |
availableLogicalSpace -= growthShare; |
| 480 |
} |
580 |
} |
|
Lines 500-506
bool RenderGrid::tracksAreWiderThanMinTrackBreadth(TrackSizingDirection directio
a/Source/WebCore/rendering/RenderGrid.cpp_sec8
|
| 500 |
{ |
600 |
{ |
| 501 |
for (size_t i = 0; i < tracks.size(); ++i) { |
601 |
for (size_t i = 0; i < tracks.size(); ++i) { |
| 502 |
const GridTrackSize& trackSize = gridTrackSize(direction, i); |
602 |
const GridTrackSize& trackSize = gridTrackSize(direction, i); |
| 503 |
const Length& minTrackBreadth = trackSize.minTrackBreadth(); |
603 |
const GridLength& minTrackBreadth = trackSize.minTrackBreadth(); |
| 504 |
if (computeUsedBreadthOfMinLength(direction, minTrackBreadth) > tracks[i].m_usedBreadth) |
604 |
if (computeUsedBreadthOfMinLength(direction, minTrackBreadth) > tracks[i].m_usedBreadth) |
| 505 |
return false; |
605 |
return false; |
| 506 |
} |
606 |
} |