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

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

Issue 2403553002: reflow comments in core/layout/[M-Z]*.{cpp,h} (Closed)
Patch Set: Created 4 years, 2 months 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) 2002 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 2002 Lars Knoll (knoll@kde.org)
3 * (C) 2002 Dirk Mueller (mueller@kde.org) 3 * (C) 2002 Dirk Mueller (mueller@kde.org)
4 * Copyright (C) 2003, 2006, 2008, 2010 Apple Inc. All rights reserved. 4 * Copyright (C) 2003, 2006, 2008, 2010 Apple Inc. All rights reserved.
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public 7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2 of the License. 9 * version 2 of the License.
10 * 10 *
(...skipping 28 matching lines...) Expand all
39 39
40 void TableLayoutAlgorithmAuto::recalcColumn(unsigned effCol) { 40 void TableLayoutAlgorithmAuto::recalcColumn(unsigned effCol) {
41 Layout& columnLayout = m_layoutStruct[effCol]; 41 Layout& columnLayout = m_layoutStruct[effCol];
42 42
43 LayoutTableCell* fixedContributor = nullptr; 43 LayoutTableCell* fixedContributor = nullptr;
44 LayoutTableCell* maxContributor = nullptr; 44 LayoutTableCell* maxContributor = nullptr;
45 45
46 for (LayoutObject* child = m_table->children()->firstChild(); child; 46 for (LayoutObject* child = m_table->children()->firstChild(); child;
47 child = child->nextSibling()) { 47 child = child->nextSibling()) {
48 if (child->isLayoutTableCol()) { 48 if (child->isLayoutTableCol()) {
49 // LayoutTableCols don't have the concept of preferred logical width, but we need to clear their dirty bits 49 // LayoutTableCols don't have the concept of preferred logical width, but
50 // so that if we call setPreferredWidthsDirty(true) on a col or one of its descendants, we'll mark it's 50 // we need to clear their dirty bits so that if we call
51 // ancestors as dirty. 51 // setPreferredWidthsDirty(true) on a col or one of its descendants, we'll
52 // mark it's ancestors as dirty.
52 toLayoutTableCol(child)->clearPreferredLogicalWidthsDirtyBits(); 53 toLayoutTableCol(child)->clearPreferredLogicalWidthsDirtyBits();
53 } else if (child->isTableSection()) { 54 } else if (child->isTableSection()) {
54 LayoutTableSection* section = toLayoutTableSection(child); 55 LayoutTableSection* section = toLayoutTableSection(child);
55 unsigned numRows = section->numRows(); 56 unsigned numRows = section->numRows();
56 for (unsigned i = 0; i < numRows; i++) { 57 for (unsigned i = 0; i < numRows; i++) {
57 LayoutTableSection::CellStruct current = section->cellAt(i, effCol); 58 LayoutTableSection::CellStruct current = section->cellAt(i, effCol);
58 LayoutTableCell* cell = current.primaryCell(); 59 LayoutTableCell* cell = current.primaryCell();
59 60
60 if (current.inColSpan || !cell) 61 if (current.inColSpan || !cell)
61 continue; 62 continue;
62 columnLayout.columnHasNoCells = false; 63 columnLayout.columnHasNoCells = false;
63 64
64 if (cell->maxPreferredLogicalWidth()) 65 if (cell->maxPreferredLogicalWidth())
65 columnLayout.emptyCellsOnly = false; 66 columnLayout.emptyCellsOnly = false;
66 67
67 if (cell->colSpan() == 1) { 68 if (cell->colSpan() == 1) {
68 columnLayout.minLogicalWidth = 69 columnLayout.minLogicalWidth =
69 std::max<int>(cell->minPreferredLogicalWidth().toInt(), 70 std::max<int>(cell->minPreferredLogicalWidth().toInt(),
70 columnLayout.minLogicalWidth); 71 columnLayout.minLogicalWidth);
71 if (cell->maxPreferredLogicalWidth() > columnLayout.maxLogicalWidth) { 72 if (cell->maxPreferredLogicalWidth() > columnLayout.maxLogicalWidth) {
72 columnLayout.maxLogicalWidth = 73 columnLayout.maxLogicalWidth =
73 cell->maxPreferredLogicalWidth().toInt(); 74 cell->maxPreferredLogicalWidth().toInt();
74 maxContributor = cell; 75 maxContributor = cell;
75 } 76 }
76 77
77 // All browsers implement a size limit on the cell's max width. 78 // All browsers implement a size limit on the cell's max width.
78 // Our limit is based on KHTML's representation that used 16 bits widt hs. 79 // Our limit is based on KHTML's representation that used 16 bits
80 // widths.
79 // FIXME: Other browsers have a lower limit for the cell's max width. 81 // FIXME: Other browsers have a lower limit for the cell's max width.
80 const int cCellMaxWidth = 32760; 82 const int cCellMaxWidth = 32760;
81 Length cellLogicalWidth = cell->styleOrColLogicalWidth(); 83 Length cellLogicalWidth = cell->styleOrColLogicalWidth();
82 // FIXME: calc() on tables should be handled consistently with other l engths. See bug: https://crbug.com/382725 84 // FIXME: calc() on tables should be handled consistently with other
85 // lengths. See bug: https://crbug.com/382725
83 if (cellLogicalWidth.isCalculated()) 86 if (cellLogicalWidth.isCalculated())
84 cellLogicalWidth = Length(); // Make it Auto 87 cellLogicalWidth = Length(); // Make it Auto
85 if (cellLogicalWidth.value() > cCellMaxWidth) 88 if (cellLogicalWidth.value() > cCellMaxWidth)
86 cellLogicalWidth.setValue(cCellMaxWidth); 89 cellLogicalWidth.setValue(cCellMaxWidth);
87 if (cellLogicalWidth.isNegative()) 90 if (cellLogicalWidth.isNegative())
88 cellLogicalWidth.setValue(0); 91 cellLogicalWidth.setValue(0);
89 switch (cellLogicalWidth.type()) { 92 switch (cellLogicalWidth.type()) {
90 case Fixed: 93 case Fixed:
91 // ignore width=0 94 // ignore width=0
92 if (cellLogicalWidth.isPositive() && 95 if (cellLogicalWidth.isPositive() &&
(...skipping 22 matching lines...) Expand all
115 if (cellLogicalWidth.isPositive() && 118 if (cellLogicalWidth.isPositive() &&
116 (!columnLayout.logicalWidth.isPercentOrCalc() || 119 (!columnLayout.logicalWidth.isPercentOrCalc() ||
117 cellLogicalWidth.value() > 120 cellLogicalWidth.value() >
118 columnLayout.logicalWidth.value())) 121 columnLayout.logicalWidth.value()))
119 columnLayout.logicalWidth = cellLogicalWidth; 122 columnLayout.logicalWidth = cellLogicalWidth;
120 break; 123 break;
121 default: 124 default:
122 break; 125 break;
123 } 126 }
124 } else if (!effCol || section->primaryCellAt(i, effCol - 1) != cell) { 127 } else if (!effCol || section->primaryCellAt(i, effCol - 1) != cell) {
125 // If a cell originates in this spanning column ensure we have a min/m ax width of at least 1px for it. 128 // If a cell originates in this spanning column ensure we have a
129 // min/max width of at least 1px for it.
126 columnLayout.minLogicalWidth = 130 columnLayout.minLogicalWidth =
127 std::max<int>(columnLayout.minLogicalWidth, 131 std::max<int>(columnLayout.minLogicalWidth,
128 cell->maxPreferredLogicalWidth() ? 1 : 0); 132 cell->maxPreferredLogicalWidth() ? 1 : 0);
129 133
130 // This spanning cell originates in this column. Insert the cell into spanning cells list. 134 // This spanning cell originates in this column. Insert the cell into
135 // spanning cells list.
131 insertSpanCell(cell); 136 insertSpanCell(cell);
132 } 137 }
133 } 138 }
134 } 139 }
135 } 140 }
136 141
137 // Nav/IE weirdness 142 // Nav/IE weirdness
138 if (columnLayout.logicalWidth.isFixed()) { 143 if (columnLayout.logicalWidth.isFixed()) {
139 if (m_table->document().inQuirksMode() && 144 if (m_table->document().inQuirksMode() &&
140 columnLayout.maxLogicalWidth > columnLayout.logicalWidth.value() && 145 columnLayout.maxLogicalWidth > columnLayout.logicalWidth.value() &&
(...skipping 17 matching lines...) Expand all
158 m_spanCells.fill(0); 163 m_spanCells.fill(0);
159 164
160 Length groupLogicalWidth; 165 Length groupLogicalWidth;
161 unsigned currentColumn = 0; 166 unsigned currentColumn = 0;
162 for (LayoutTableCol* column = m_table->firstColumn(); column; 167 for (LayoutTableCol* column = m_table->firstColumn(); column;
163 column = column->nextColumn()) { 168 column = column->nextColumn()) {
164 if (column->isTableColumnGroupWithColumnChildren()) { 169 if (column->isTableColumnGroupWithColumnChildren()) {
165 groupLogicalWidth = column->style()->logicalWidth(); 170 groupLogicalWidth = column->style()->logicalWidth();
166 } else { 171 } else {
167 Length colLogicalWidth = column->style()->logicalWidth(); 172 Length colLogicalWidth = column->style()->logicalWidth();
168 // FIXME: calc() on tables should be handled consistently with other lengt hs. See bug: https://crbug.com/382725 173 // FIXME: calc() on tables should be handled consistently with other
174 // lengths. See bug: https://crbug.com/382725
169 if (colLogicalWidth.isCalculated() || colLogicalWidth.isAuto()) 175 if (colLogicalWidth.isCalculated() || colLogicalWidth.isAuto())
170 colLogicalWidth = groupLogicalWidth; 176 colLogicalWidth = groupLogicalWidth;
171 // TODO(alancutter): Make this work correctly for calc lengths. 177 // TODO(alancutter): Make this work correctly for calc lengths.
172 if ((colLogicalWidth.isFixed() || colLogicalWidth.isPercentOrCalc()) && 178 if ((colLogicalWidth.isFixed() || colLogicalWidth.isPercentOrCalc()) &&
173 colLogicalWidth.isZero()) 179 colLogicalWidth.isZero())
174 colLogicalWidth = Length(); 180 colLogicalWidth = Length();
175 unsigned effCol = m_table->absoluteColumnToEffectiveColumn(currentColumn); 181 unsigned effCol = m_table->absoluteColumnToEffectiveColumn(currentColumn);
176 unsigned span = column->span(); 182 unsigned span = column->span();
177 if (!colLogicalWidth.isAuto() && span == 1 && effCol < nEffCols && 183 if (!colLogicalWidth.isAuto() && span == 1 && effCol < nEffCols &&
178 m_table->spanOfEffectiveColumn(effCol) == 1) { 184 m_table->spanOfEffectiveColumn(effCol) == 1) {
179 m_layoutStruct[effCol].logicalWidth = colLogicalWidth; 185 m_layoutStruct[effCol].logicalWidth = colLogicalWidth;
180 if (colLogicalWidth.isFixed() && 186 if (colLogicalWidth.isFixed() &&
181 m_layoutStruct[effCol].maxLogicalWidth < colLogicalWidth.value()) 187 m_layoutStruct[effCol].maxLogicalWidth < colLogicalWidth.value())
182 m_layoutStruct[effCol].maxLogicalWidth = colLogicalWidth.value(); 188 m_layoutStruct[effCol].maxLogicalWidth = colLogicalWidth.value();
183 } 189 }
184 currentColumn += span; 190 currentColumn += span;
185 } 191 }
186 192
187 // For the last column in a column-group, we invalidate our group logical wi dth. 193 // For the last column in a column-group, we invalidate our group logical
194 // width.
188 if (column->isTableColumn() && !column->nextSibling()) 195 if (column->isTableColumn() && !column->nextSibling())
189 groupLogicalWidth = Length(); 196 groupLogicalWidth = Length();
190 } 197 }
191 198
192 for (unsigned i = 0; i < nEffCols; i++) 199 for (unsigned i = 0; i < nEffCols; i++)
193 recalcColumn(i); 200 recalcColumn(i);
194 } 201 }
195 202
196 static bool shouldScaleColumnsForParent(LayoutTable* table) { 203 static bool shouldScaleColumnsForParent(LayoutTable* table) {
197 LayoutBlock* cb = table->containingBlock(); 204 LayoutBlock* cb = table->containingBlock();
198 while (!cb->isLayoutView()) { 205 while (!cb->isLayoutView()) {
199 // It doesn't matter if our table is auto or fixed: auto means we don't 206 // It doesn't matter if our table is auto or fixed: auto means we don't
200 // scale. Fixed doesn't care if we do or not because it doesn't depend 207 // scale. Fixed doesn't care if we do or not because it doesn't depend
201 // on the cell contents' preferred widths. 208 // on the cell contents' preferred widths.
202 if (cb->isTableCell()) 209 if (cb->isTableCell())
203 return false; 210 return false;
204 cb = cb->containingBlock(); 211 cb = cb->containingBlock();
205 } 212 }
206 return true; 213 return true;
207 } 214 }
208 215
209 // FIXME: This needs to be adapted for vertical writing modes. 216 // FIXME: This needs to be adapted for vertical writing modes.
210 static bool shouldScaleColumnsForSelf(LayoutTable* table) { 217 static bool shouldScaleColumnsForSelf(LayoutTable* table) {
211 // Normally, scale all columns to satisfy this from CSS2.2: 218 // Normally, scale all columns to satisfy this from CSS2.2:
212 // "A percentage value for a column width is relative to the table width. 219 // "A percentage value for a column width is relative to the table width.
213 // If the table has 'width: auto', a percentage represents a constraint on the column's width" 220 // If the table has 'width: auto', a percentage represents a constraint on the
221 // column's width"
214 222
215 // A special case. If this table is not fixed width and contained inside 223 // A special case. If this table is not fixed width and contained inside
216 // a cell, then don't bloat the maxwidth by examining percentage growth. 224 // a cell, then don't bloat the maxwidth by examining percentage growth.
217 while (true) { 225 while (true) {
218 Length tw = table->style()->width(); 226 Length tw = table->style()->width();
219 if ((!tw.isAuto() && !tw.isPercentOrCalc()) || 227 if ((!tw.isAuto() && !tw.isPercentOrCalc()) ||
220 table->isOutOfFlowPositioned()) 228 table->isOutOfFlowPositioned())
221 return true; 229 return true;
222 LayoutBlock* cb = table->containingBlock(); 230 LayoutBlock* cb = table->containingBlock();
223 231
(...skipping 22 matching lines...) Expand all
246 254
247 fullRecalc(); 255 fullRecalc();
248 256
249 int spanMaxLogicalWidth = calcEffectiveLogicalWidth(); 257 int spanMaxLogicalWidth = calcEffectiveLogicalWidth();
250 minWidth = LayoutUnit(); 258 minWidth = LayoutUnit();
251 maxWidth = LayoutUnit(); 259 maxWidth = LayoutUnit();
252 float maxPercent = 0; 260 float maxPercent = 0;
253 float maxNonPercent = 0; 261 float maxNonPercent = 0;
254 bool scaleColumnsForSelf = shouldScaleColumnsForSelf(m_table); 262 bool scaleColumnsForSelf = shouldScaleColumnsForSelf(m_table);
255 263
256 // We substitute 0 percent by (epsilon / percentScaleFactor) percent in two pl aces below to avoid division by zero. 264 // We substitute 0 percent by (epsilon / percentScaleFactor) percent in two
265 // places below to avoid division by zero.
257 // FIXME: Handle the 0% cases properly. 266 // FIXME: Handle the 0% cases properly.
258 const float epsilon = 1 / 128.0f; 267 const float epsilon = 1 / 128.0f;
259 268
260 float remainingPercent = 100; 269 float remainingPercent = 100;
261 for (size_t i = 0; i < m_layoutStruct.size(); ++i) { 270 for (size_t i = 0; i < m_layoutStruct.size(); ++i) {
262 minWidth += m_layoutStruct[i].effectiveMinLogicalWidth; 271 minWidth += m_layoutStruct[i].effectiveMinLogicalWidth;
263 maxWidth += m_layoutStruct[i].effectiveMaxLogicalWidth; 272 maxWidth += m_layoutStruct[i].effectiveMaxLogicalWidth;
264 if (scaleColumnsForSelf) { 273 if (scaleColumnsForSelf) {
265 if (m_layoutStruct[i].effectiveLogicalWidth.isPercentOrCalc()) { 274 if (m_layoutStruct[i].effectiveLogicalWidth.isPercentOrCalc()) {
266 float percent = 275 float percent =
(...skipping 24 matching lines...) Expand all
291 } 300 }
292 301
293 maxWidth = LayoutUnit(std::max(maxWidth.floor(), spanMaxLogicalWidth)); 302 maxWidth = LayoutUnit(std::max(maxWidth.floor(), spanMaxLogicalWidth));
294 } 303 }
295 304
296 void TableLayoutAlgorithmAuto::applyPreferredLogicalWidthQuirks( 305 void TableLayoutAlgorithmAuto::applyPreferredLogicalWidthQuirks(
297 LayoutUnit& minWidth, 306 LayoutUnit& minWidth,
298 LayoutUnit& maxWidth) const { 307 LayoutUnit& maxWidth) const {
299 Length tableLogicalWidth = m_table->style()->logicalWidth(); 308 Length tableLogicalWidth = m_table->style()->logicalWidth();
300 if (tableLogicalWidth.isFixed() && tableLogicalWidth.isPositive()) { 309 if (tableLogicalWidth.isFixed() && tableLogicalWidth.isPositive()) {
301 // |minWidth| is the result of measuring the intrinsic content's size. Keep it to 310 // |minWidth| is the result of measuring the intrinsic content's size. Keep
302 // make sure we are *never* smaller than the actual content. 311 // it to make sure we are *never* smaller than the actual content.
303 LayoutUnit minContentWidth = minWidth; 312 LayoutUnit minContentWidth = minWidth;
304 // FIXME: This line looks REALLY suspicious as it could allow the minimum 313 // FIXME: This line looks REALLY suspicious as it could allow the minimum
305 // preferred logical width to be smaller than the table content. This has 314 // preferred logical width to be smaller than the table content. This has
306 // to be cross-checked against other browsers. 315 // to be cross-checked against other browsers.
307 minWidth = maxWidth = 316 minWidth = maxWidth =
308 LayoutUnit(std::max<int>(minWidth.floor(), tableLogicalWidth.value())); 317 LayoutUnit(std::max<int>(minWidth.floor(), tableLogicalWidth.value()));
309 318
310 const Length& styleMaxLogicalWidth = m_table->style()->logicalMaxWidth(); 319 const Length& styleMaxLogicalWidth = m_table->style()->logicalMaxWidth();
311 if (styleMaxLogicalWidth.isFixed() && !styleMaxLogicalWidth.isNegative()) { 320 if (styleMaxLogicalWidth.isFixed() && !styleMaxLogicalWidth.isNegative()) {
312 minWidth = LayoutUnit( 321 minWidth = LayoutUnit(
313 std::min<int>(minWidth.floor(), styleMaxLogicalWidth.value())); 322 std::min<int>(minWidth.floor(), styleMaxLogicalWidth.value()));
314 minWidth = std::max(minWidth, minContentWidth); 323 minWidth = std::max(minWidth, minContentWidth);
315 maxWidth = minWidth; 324 maxWidth = minWidth;
316 } 325 }
317 } 326 }
318 } 327 }
319 328
320 /* 329 /*
321 This method takes care of colspans. 330 This method takes care of colspans.
322 effWidth is the same as width for cells without colspans. If we have colspans, they get modified. 331 effWidth is the same as width for cells without colspans. If we have colspans,
332 they get modified.
dcheng 2016/10/07 20:42:01 A wild C-style comment!
323 */ 333 */
324 int TableLayoutAlgorithmAuto::calcEffectiveLogicalWidth() { 334 int TableLayoutAlgorithmAuto::calcEffectiveLogicalWidth() {
325 int maxLogicalWidth = 0; 335 int maxLogicalWidth = 0;
326 336
327 size_t nEffCols = m_layoutStruct.size(); 337 size_t nEffCols = m_layoutStruct.size();
328 int spacingInRowDirection = m_table->hBorderSpacing(); 338 int spacingInRowDirection = m_table->hBorderSpacing();
329 339
330 for (size_t i = 0; i < nEffCols; ++i) { 340 for (size_t i = 0; i < nEffCols; ++i) {
331 m_layoutStruct[i].effectiveLogicalWidth = m_layoutStruct[i].logicalWidth; 341 m_layoutStruct[i].effectiveLogicalWidth = m_layoutStruct[i].logicalWidth;
332 m_layoutStruct[i].effectiveMinLogicalWidth = 342 m_layoutStruct[i].effectiveMinLogicalWidth =
333 m_layoutStruct[i].minLogicalWidth; 343 m_layoutStruct[i].minLogicalWidth;
334 m_layoutStruct[i].effectiveMaxLogicalWidth = 344 m_layoutStruct[i].effectiveMaxLogicalWidth =
335 m_layoutStruct[i].maxLogicalWidth; 345 m_layoutStruct[i].maxLogicalWidth;
336 } 346 }
337 347
338 for (size_t i = 0; i < m_spanCells.size(); ++i) { 348 for (size_t i = 0; i < m_spanCells.size(); ++i) {
339 LayoutTableCell* cell = m_spanCells[i]; 349 LayoutTableCell* cell = m_spanCells[i];
340 if (!cell) 350 if (!cell)
341 break; 351 break;
342 352
343 unsigned span = cell->colSpan(); 353 unsigned span = cell->colSpan();
344 354
345 Length cellLogicalWidth = cell->styleOrColLogicalWidth(); 355 Length cellLogicalWidth = cell->styleOrColLogicalWidth();
346 // FIXME: calc() on tables should be handled consistently with other lengths . See bug: https://crbug.com/382725 356 // FIXME: calc() on tables should be handled consistently with other
357 // lengths. See bug: https://crbug.com/382725
347 if (cellLogicalWidth.isZero() || cellLogicalWidth.isCalculated()) 358 if (cellLogicalWidth.isZero() || cellLogicalWidth.isCalculated())
348 cellLogicalWidth = Length(); // Make it Auto 359 cellLogicalWidth = Length(); // Make it Auto
349 360
350 unsigned effCol = 361 unsigned effCol =
351 m_table->absoluteColumnToEffectiveColumn(cell->absoluteColumnIndex()); 362 m_table->absoluteColumnToEffectiveColumn(cell->absoluteColumnIndex());
352 size_t lastCol = effCol; 363 size_t lastCol = effCol;
353 int cellMinLogicalWidth = 364 int cellMinLogicalWidth =
354 (cell->minPreferredLogicalWidth() + spacingInRowDirection).toInt(); 365 (cell->minPreferredLogicalWidth() + spacingInRowDirection).toInt();
355 int cellMaxLogicalWidth = 366 int cellMaxLogicalWidth =
356 (cell->maxPreferredLogicalWidth() + spacingInRowDirection).toInt(); 367 (cell->maxPreferredLogicalWidth() + spacingInRowDirection).toInt();
357 float totalPercent = 0; 368 float totalPercent = 0;
358 int spanMinLogicalWidth = 0; 369 int spanMinLogicalWidth = 0;
359 int spanMaxLogicalWidth = 0; 370 int spanMaxLogicalWidth = 0;
360 bool allColsArePercent = true; 371 bool allColsArePercent = true;
361 bool allColsAreFixed = true; 372 bool allColsAreFixed = true;
362 bool haveAuto = false; 373 bool haveAuto = false;
363 bool spanHasEmptyCellsOnly = true; 374 bool spanHasEmptyCellsOnly = true;
364 int fixedWidth = 0; 375 int fixedWidth = 0;
365 while (lastCol < nEffCols && span > 0) { 376 while (lastCol < nEffCols && span > 0) {
366 Layout& columnLayout = m_layoutStruct[lastCol]; 377 Layout& columnLayout = m_layoutStruct[lastCol];
367 switch (columnLayout.logicalWidth.type()) { 378 switch (columnLayout.logicalWidth.type()) {
368 case Percent: 379 case Percent:
369 totalPercent += columnLayout.logicalWidth.percent(); 380 totalPercent += columnLayout.logicalWidth.percent();
370 allColsAreFixed = false; 381 allColsAreFixed = false;
371 break; 382 break;
372 case Fixed: 383 case Fixed:
373 if (columnLayout.logicalWidth.value() > 0) { 384 if (columnLayout.logicalWidth.value() > 0) {
374 fixedWidth += columnLayout.logicalWidth.value(); 385 fixedWidth += columnLayout.logicalWidth.value();
375 allColsArePercent = false; 386 allColsArePercent = false;
376 // IE resets effWidth to Auto here, but this breaks the konqueror ab out page and seems to be some bad 387 // IE resets effWidth to Auto here, but this breaks the konqueror
377 // legacy behaviour anyway. mozilla doesn't do this so I decided we don't neither. 388 // about page and seems to be some bad legacy behaviour anyway.
389 // mozilla doesn't do this so I decided we don't neither.
378 break; 390 break;
379 } 391 }
380 // fall through 392 // fall through
381 case Auto: 393 case Auto:
382 haveAuto = true; 394 haveAuto = true;
383 // fall through 395 // fall through
384 default: 396 default:
385 // If the column is a percentage width, do not let the spanning cell o verwrite the 397 // If the column is a percentage width, do not let the spanning cell
386 // width value. This caused a mis-layout on amazon.com. 398 // overwrite the width value. This caused a mis-layout on amazon.com.
387 // Sample snippet: 399 // Sample snippet:
388 // <table border=2 width=100%>< 400 // <table border=2 width=100%><
389 // <tr><td>1</td><td colspan=2>2-3</tr> 401 // <tr><td>1</td><td colspan=2>2-3</tr>
390 // <tr><td>1</td><td colspan=2 width=100%>2-3</td></tr> 402 // <tr><td>1</td><td colspan=2 width=100%>2-3</td></tr>
391 // </table> 403 // </table>
392 // TODO(alancutter): Make this work correctly for calc lengths. 404 // TODO(alancutter): Make this work correctly for calc lengths.
393 if (!columnLayout.effectiveLogicalWidth.isPercentOrCalc()) { 405 if (!columnLayout.effectiveLogicalWidth.isPercentOrCalc()) {
394 columnLayout.effectiveLogicalWidth = Length(); 406 columnLayout.effectiveLogicalWidth = Length();
395 allColsArePercent = false; 407 allColsArePercent = false;
396 } else { 408 } else {
(...skipping 16 matching lines...) Expand all
413 if (totalPercent > cellLogicalWidth.percent() || allColsArePercent) { 425 if (totalPercent > cellLogicalWidth.percent() || allColsArePercent) {
414 // can't satify this condition, treat as variable 426 // can't satify this condition, treat as variable
415 cellLogicalWidth = Length(); 427 cellLogicalWidth = Length();
416 } else { 428 } else {
417 maxLogicalWidth = 429 maxLogicalWidth =
418 std::max(maxLogicalWidth, 430 std::max(maxLogicalWidth,
419 static_cast<int>( 431 static_cast<int>(
420 std::max(spanMaxLogicalWidth, cellMaxLogicalWidth) * 432 std::max(spanMaxLogicalWidth, cellMaxLogicalWidth) *
421 100 / cellLogicalWidth.percent())); 433 100 / cellLogicalWidth.percent()));
422 434
423 // all non percent columns in the span get percent values to sum up corr ectly. 435 // all non percent columns in the span get percent values to sum up
436 // correctly.
424 float percentMissing = cellLogicalWidth.percent() - totalPercent; 437 float percentMissing = cellLogicalWidth.percent() - totalPercent;
425 int totalWidth = 0; 438 int totalWidth = 0;
426 for (unsigned pos = effCol; pos < lastCol; ++pos) { 439 for (unsigned pos = effCol; pos < lastCol; ++pos) {
427 if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercentOrCalc()) 440 if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercentOrCalc())
428 totalWidth += m_layoutStruct[pos].clampedEffectiveMaxLogicalWidth(); 441 totalWidth += m_layoutStruct[pos].clampedEffectiveMaxLogicalWidth();
429 } 442 }
430 443
431 for (unsigned pos = effCol; pos < lastCol && totalWidth > 0; ++pos) { 444 for (unsigned pos = effCol; pos < lastCol && totalWidth > 0; ++pos) {
432 if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercentOrCalc()) { 445 if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercentOrCalc()) {
433 float percent = percentMissing * 446 float percent = percentMissing *
(...skipping 19 matching lines...) Expand all
453 int cellLogicalWidth = std::max( 466 int cellLogicalWidth = std::max(
454 m_layoutStruct[pos].effectiveMinLogicalWidth, 467 m_layoutStruct[pos].effectiveMinLogicalWidth,
455 static_cast<int>(cellMinLogicalWidth * 468 static_cast<int>(cellMinLogicalWidth *
456 m_layoutStruct[pos].logicalWidth.value() / 469 m_layoutStruct[pos].logicalWidth.value() /
457 fixedWidth)); 470 fixedWidth));
458 fixedWidth -= m_layoutStruct[pos].logicalWidth.value(); 471 fixedWidth -= m_layoutStruct[pos].logicalWidth.value();
459 cellMinLogicalWidth -= cellLogicalWidth; 472 cellMinLogicalWidth -= cellLogicalWidth;
460 m_layoutStruct[pos].effectiveMinLogicalWidth = cellLogicalWidth; 473 m_layoutStruct[pos].effectiveMinLogicalWidth = cellLogicalWidth;
461 } 474 }
462 } else if (allColsArePercent) { 475 } else if (allColsArePercent) {
463 // In this case, we just split the colspan's min amd max widths followin g the percentage. 476 // In this case, we just split the colspan's min amd max widths
477 // following the percentage.
464 int allocatedMinLogicalWidth = 0; 478 int allocatedMinLogicalWidth = 0;
465 int allocatedMaxLogicalWidth = 0; 479 int allocatedMaxLogicalWidth = 0;
466 for (unsigned pos = effCol; pos < lastCol; ++pos) { 480 for (unsigned pos = effCol; pos < lastCol; ++pos) {
467 // TODO(alancutter): Make this work correctly for calc lengths. 481 // TODO(alancutter): Make this work correctly for calc lengths.
468 DCHECK(m_layoutStruct[pos].logicalWidth.isPercentOrCalc() || 482 DCHECK(m_layoutStruct[pos].logicalWidth.isPercentOrCalc() ||
469 m_layoutStruct[pos].effectiveLogicalWidth.isPercentOrCalc()); 483 m_layoutStruct[pos].effectiveLogicalWidth.isPercentOrCalc());
470 // |allColsArePercent| means that either the logicalWidth *or* the eff ectiveLogicalWidth are percents, handle both of them here. 484 // |allColsArePercent| means that either the logicalWidth *or* the
485 // effectiveLogicalWidth are percents, handle both of them here.
471 float percent = 486 float percent =
472 m_layoutStruct[pos].logicalWidth.isPercentOrCalc() 487 m_layoutStruct[pos].logicalWidth.isPercentOrCalc()
473 ? m_layoutStruct[pos].logicalWidth.percent() 488 ? m_layoutStruct[pos].logicalWidth.percent()
474 : m_layoutStruct[pos].effectiveLogicalWidth.percent(); 489 : m_layoutStruct[pos].effectiveLogicalWidth.percent();
475 int columnMinLogicalWidth = 490 int columnMinLogicalWidth =
476 static_cast<int>(percent * cellMinLogicalWidth / totalPercent); 491 static_cast<int>(percent * cellMinLogicalWidth / totalPercent);
477 int columnMaxLogicalWidth = 492 int columnMaxLogicalWidth =
478 static_cast<int>(percent * cellMaxLogicalWidth / totalPercent); 493 static_cast<int>(percent * cellMaxLogicalWidth / totalPercent);
479 m_layoutStruct[pos].effectiveMinLogicalWidth = 494 m_layoutStruct[pos].effectiveMinLogicalWidth =
480 std::max(m_layoutStruct[pos].effectiveMinLogicalWidth, 495 std::max(m_layoutStruct[pos].effectiveMinLogicalWidth,
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 return; 598 return;
584 599
585 unsigned size = m_spanCells.size(); 600 unsigned size = m_spanCells.size();
586 if (!size || m_spanCells[size - 1] != 0) { 601 if (!size || m_spanCells[size - 1] != 0) {
587 m_spanCells.grow(size + 10); 602 m_spanCells.grow(size + 10);
588 for (unsigned i = 0; i < 10; i++) 603 for (unsigned i = 0; i < 10; i++)
589 m_spanCells[size + i] = 0; 604 m_spanCells[size + i] = 0;
590 size += 10; 605 size += 10;
591 } 606 }
592 607
593 // add them in sort. This is a slow algorithm, and a binary search or a fast s orting after collection would be better 608 // Add them in sort. This is a slow algorithm, and a binary search or a fast
609 // sorting after collection would be better.
594 unsigned pos = 0; 610 unsigned pos = 0;
595 unsigned span = cell->colSpan(); 611 unsigned span = cell->colSpan();
596 while (pos < m_spanCells.size() && m_spanCells[pos] && 612 while (pos < m_spanCells.size() && m_spanCells[pos] &&
597 span > m_spanCells[pos]->colSpan()) 613 span > m_spanCells[pos]->colSpan())
598 pos++; 614 pos++;
599 memmove(m_spanCells.data() + pos + 1, m_spanCells.data() + pos, 615 memmove(m_spanCells.data() + pos + 1, m_spanCells.data() + pos,
600 (size - pos - 1) * sizeof(LayoutTableCell*)); 616 (size - pos - 1) * sizeof(LayoutTableCell*));
601 m_spanCells[pos] = cell; 617 m_spanCells[pos] = cell;
602 } 618 }
603 619
604 void TableLayoutAlgorithmAuto::layout() { 620 void TableLayoutAlgorithmAuto::layout() {
605 // table layout based on the values collected in the layout structure. 621 // table layout based on the values collected in the layout structure.
606 int tableLogicalWidth = (m_table->logicalWidth() - 622 int tableLogicalWidth = (m_table->logicalWidth() -
607 m_table->bordersPaddingAndSpacingInRowDirection()) 623 m_table->bordersPaddingAndSpacingInRowDirection())
608 .toInt(); 624 .toInt();
609 int available = tableLogicalWidth; 625 int available = tableLogicalWidth;
610 size_t nEffCols = m_table->numEffectiveColumns(); 626 size_t nEffCols = m_table->numEffectiveColumns();
611 627
612 // FIXME: It is possible to be called without having properly updated our inte rnal representation. 628 // FIXME: It is possible to be called without having properly updated our
613 // This means that our preferred logical widths were not recomputed as expecte d. 629 // internal representation. This means that our preferred logical widths were
dcheng 2016/10/07 20:42:01 I don't feel that strongly about this (but it is i
630 // not recomputed as expected.
614 if (nEffCols != m_layoutStruct.size()) { 631 if (nEffCols != m_layoutStruct.size()) {
615 fullRecalc(); 632 fullRecalc();
616 // FIXME: Table layout shouldn't modify our table structure (but does due to columns and column-groups). 633 // FIXME: Table layout shouldn't modify our table structure (but does due to
634 // columns and column-groups).
617 nEffCols = m_table->numEffectiveColumns(); 635 nEffCols = m_table->numEffectiveColumns();
618 } 636 }
619 637
620 if (m_effectiveLogicalWidthDirty) 638 if (m_effectiveLogicalWidthDirty)
621 calcEffectiveLogicalWidth(); 639 calcEffectiveLogicalWidth();
622 640
623 bool havePercent = false; 641 bool havePercent = false;
624 int numAuto = 0; 642 int numAuto = 0;
625 int numFixed = 0; 643 int numFixed = 0;
626 float totalAuto = 0; 644 float totalAuto = 0;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 } 692 }
675 } 693 }
676 if (totalPercent > 100) { 694 if (totalPercent > 100) {
677 // remove overallocated space from the last columns 695 // remove overallocated space from the last columns
678 int excess = tableLogicalWidth * (totalPercent - 100) / 100; 696 int excess = tableLogicalWidth * (totalPercent - 100) / 100;
679 for (unsigned i = nEffCols; i;) { 697 for (unsigned i = nEffCols; i;) {
680 --i; 698 --i;
681 if (m_layoutStruct[i].effectiveLogicalWidth.isPercentOrCalc()) { 699 if (m_layoutStruct[i].effectiveLogicalWidth.isPercentOrCalc()) {
682 int cellLogicalWidth = m_layoutStruct[i].computedLogicalWidth; 700 int cellLogicalWidth = m_layoutStruct[i].computedLogicalWidth;
683 int reduction = std::min(cellLogicalWidth, excess); 701 int reduction = std::min(cellLogicalWidth, excess);
684 // the lines below might look inconsistent, but that's the way it's ha ndled in mozilla 702 // The lines below might look inconsistent, but that's the way it's
703 // handled in mozilla.
685 excess -= reduction; 704 excess -= reduction;
686 int newLogicalWidth = 705 int newLogicalWidth =
687 std::max<int>(m_layoutStruct[i].effectiveMinLogicalWidth, 706 std::max<int>(m_layoutStruct[i].effectiveMinLogicalWidth,
688 cellLogicalWidth - reduction); 707 cellLogicalWidth - reduction);
689 available += cellLogicalWidth - newLogicalWidth; 708 available += cellLogicalWidth - newLogicalWidth;
690 m_layoutStruct[i].computedLogicalWidth = newLogicalWidth; 709 m_layoutStruct[i].computedLogicalWidth = newLogicalWidth;
691 } 710 }
692 } 711 }
693 } 712 }
694 } 713 }
695 714
696 // then allocate width to fixed cols 715 // then allocate width to fixed cols
697 if (available > 0) { 716 if (available > 0) {
698 for (size_t i = 0; i < nEffCols; ++i) { 717 for (size_t i = 0; i < nEffCols; ++i) {
699 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; 718 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth;
700 if (logicalWidth.isFixed() && 719 if (logicalWidth.isFixed() &&
701 logicalWidth.value() > m_layoutStruct[i].computedLogicalWidth) { 720 logicalWidth.value() > m_layoutStruct[i].computedLogicalWidth) {
702 available += 721 available +=
703 m_layoutStruct[i].computedLogicalWidth - logicalWidth.value(); 722 m_layoutStruct[i].computedLogicalWidth - logicalWidth.value();
704 m_layoutStruct[i].computedLogicalWidth = logicalWidth.value(); 723 m_layoutStruct[i].computedLogicalWidth = logicalWidth.value();
705 } 724 }
706 } 725 }
707 } 726 }
708 727
709 // Give each auto width column its share of the available width, non-empty col umns then empty columns. 728 // Give each auto width column its share of the available width, non-empty
729 // columns then empty columns.
710 if (available > 0 && (numAuto || numAutoEmptyCellsOnly)) { 730 if (available > 0 && (numAuto || numAutoEmptyCellsOnly)) {
711 available += allocAuto; 731 available += allocAuto;
712 if (numAuto) 732 if (numAuto)
713 distributeWidthToColumns<float, Auto, NonEmptyCells, InitialWidth, 733 distributeWidthToColumns<float, Auto, NonEmptyCells, InitialWidth,
714 StartToEnd>(available, totalAuto); 734 StartToEnd>(available, totalAuto);
715 if (numAutoEmptyCellsOnly) 735 if (numAutoEmptyCellsOnly)
716 distributeWidthToColumns<unsigned, Auto, EmptyCells, InitialWidth, 736 distributeWidthToColumns<unsigned, Auto, EmptyCells, InitialWidth,
717 StartToEnd>(available, numAutoEmptyCellsOnly); 737 StartToEnd>(available, numAutoEmptyCellsOnly);
718 } 738 }
719 739
720 // Any remaining available width expands fixed width, percent width, and non-e mpty auto width columns, in that order. 740 // Any remaining available width expands fixed width, percent width, and
741 // non-empty auto width columns, in that order.
721 if (available > 0 && numFixed) 742 if (available > 0 && numFixed)
722 distributeWidthToColumns<float, Fixed, AllCells, ExtraWidth, StartToEnd>( 743 distributeWidthToColumns<float, Fixed, AllCells, ExtraWidth, StartToEnd>(
723 available, totalFixed); 744 available, totalFixed);
724 745
725 if (available > 0 && m_hasPercent && totalPercent < 100) 746 if (available > 0 && m_hasPercent && totalPercent < 100)
726 distributeWidthToColumns<float, Percent, AllCells, ExtraWidth, StartToEnd>( 747 distributeWidthToColumns<float, Percent, AllCells, ExtraWidth, StartToEnd>(
727 available, totalPercent); 748 available, totalPercent);
728 749
729 if (available > 0 && nEffCols > numAutoEmptyCellsOnly) { 750 if (available > 0 && nEffCols > numAutoEmptyCellsOnly) {
730 unsigned total = nEffCols - numAutoEmptyCellsOnly; 751 unsigned total = nEffCols - numAutoEmptyCellsOnly;
731 // Starting from the last cell is for compatibility with FF/IE - it isn't sp ecified anywhere. 752 // Starting from the last cell is for compatibility with FF/IE - it isn't
753 // specified anywhere.
732 distributeWidthToColumns<unsigned, Auto, NonEmptyCells, LeftoverWidth, 754 distributeWidthToColumns<unsigned, Auto, NonEmptyCells, LeftoverWidth,
733 EndToStart>(available, total); 755 EndToStart>(available, total);
734 } 756 }
735 757
736 // If we have overallocated, reduce every cell according to the difference bet ween desired width and minwidth 758 // If we have overallocated, reduce every cell according to the difference
737 // this seems to produce to the pixel exact results with IE. Wonder is some of this also holds for width distributing. 759 // between desired width and minwidth. This seems to produce to the pixel
738 // This is basically the reverse of how we grew the cells. 760 // exact results with IE. Wonder is some of this also holds for width
761 // distributing. This is basically the reverse of how we grew the cells.
739 if (available < 0) 762 if (available < 0)
740 shrinkColumnWidth(Auto, available); 763 shrinkColumnWidth(Auto, available);
741 if (available < 0) 764 if (available < 0)
742 shrinkColumnWidth(Fixed, available); 765 shrinkColumnWidth(Fixed, available);
743 if (available < 0) 766 if (available < 0)
744 shrinkColumnWidth(Percent, available); 767 shrinkColumnWidth(Percent, available);
745 768
746 ASSERT(m_table->effectiveColumnPositions().size() == nEffCols + 1); 769 ASSERT(m_table->effectiveColumnPositions().size() == nEffCols + 1);
747 int pos = 0; 770 int pos = 0;
748 for (size_t i = 0; i < nEffCols; ++i) { 771 for (size_t i = 0; i < nEffCols; ++i) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 int reduce = available * minMaxDiff / logicalWidthBeyondMin; 851 int reduce = available * minMaxDiff / logicalWidthBeyondMin;
829 m_layoutStruct[i].computedLogicalWidth += reduce; 852 m_layoutStruct[i].computedLogicalWidth += reduce;
830 available -= reduce; 853 available -= reduce;
831 logicalWidthBeyondMin -= minMaxDiff; 854 logicalWidthBeyondMin -= minMaxDiff;
832 if (available >= 0) 855 if (available >= 0)
833 break; 856 break;
834 } 857 }
835 } 858 }
836 } 859 }
837 } // namespace blink 860 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698