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

Side by Side Diff: Source/core/rendering/RenderTableSection.cpp

Issue 18050007: Height of fixed height cell is not proper when cell's row is under row spanning cell. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 5 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) 1997 Martin Jones (mjones@kde.org) 2 * Copyright (C) 1997 Martin Jones (mjones@kde.org)
3 * (C) 1997 Torben Weis (weis@kde.org) 3 * (C) 1997 Torben Weis (weis@kde.org)
4 * (C) 1998 Waldo Bastian (bastian@kde.org) 4 * (C) 1998 Waldo Bastian (bastian@kde.org)
5 * (C) 1999 Lars Knoll (knoll@kde.org) 5 * (C) 1999 Lars Knoll (knoll@kde.org)
6 * (C) 1999 Antti Koivisto (koivisto@kde.org) 6 * (C) 1999 Antti Koivisto (koivisto@kde.org)
7 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved. 7 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
8 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) 8 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
9 * 9 *
10 * This library is free software; you can redistribute it and/or 10 * This library is free software; you can redistribute it and/or
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 if (inColSpan) 245 if (inColSpan)
246 c.inColSpan = true; 246 c.inColSpan = true;
247 } 247 }
248 m_cCol++; 248 m_cCol++;
249 cSpan -= currentSpan; 249 cSpan -= currentSpan;
250 inColSpan = true; 250 inColSpan = true;
251 } 251 }
252 cell->setCol(table()->effColToCol(col)); 252 cell->setCol(table()->effColToCol(col));
253 } 253 }
254 254
255 void RenderTableSection::populateSpanningRowsHeightFromCell(RenderTableCell* cel l, struct SpanningRowsHeight& spanningRowsHeight)
256 {
257 const unsigned rowSpan = cell->rowSpan();
258 const unsigned rowIndex = cell->rowIndex();
259
260 spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing = cell->logicalHe ightForRowSizing();
261
262 spanningRowsHeight.rowHeight.resize(rowSpan);
263 spanningRowsHeight.totalRowsHeight = 0;
264 for (unsigned row = 0; row < rowSpan; row++) {
265 unsigned actualRow = row + rowIndex;
266 spanningRowsHeight.rowHeight[row] = m_rowPos[actualRow + 1] - m_rowPos[a ctualRow] - borderSpacingForRow(actualRow);
267 spanningRowsHeight.totalRowsHeight += spanningRowsHeight.rowHeight[row];
268 spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing -= borderSpac ingForRow(actualRow);
269 }
270 // We don't span the following row so its border-spacing (if any) should be included.
271 spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing += borderSpacingF orRow(rowIndex + rowSpan - 1);
272 }
273
274 void RenderTableSection::distributeExtraRowSpanHeightToPercentRows(RenderTableCe ll* cell, int totalPercent, int& extraRowSpanningHeight, Vector<int>& rowsHeight )
275 {
276 if (!extraRowSpanningHeight || !totalPercent)
277 return;
278
279 const unsigned rowSpan = cell->rowSpan();
280 const unsigned rowIndex = cell->rowIndex();
281 int percent = min(totalPercent, 100);
282 const int tableHeight = m_rowPos[m_grid.size()] + extraRowSpanningHeight;
283
284 // Our algorithm matches Firefox. Extra spanning height would be distributed Only in first percent height rows
285 // those total percent is 100. Other percent rows would be uneffected even e xtra spanning height is remain.
286 int accumulatedPositionIncrease = 0;
287 for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) {
288 if (percent > 0 && extraRowSpanningHeight > 0) {
289 if (m_grid[row].logicalHeight.isPercent()) {
290 int toAdd = (tableHeight * m_grid[row].logicalHeight.percent() / 100) - rowsHeight[row - rowIndex];
291 // FIXME: Note that this is wrong if we have a percentage above 100% and may make us grow
292 // above the available space.
293
294 toAdd = min(toAdd, extraRowSpanningHeight);
295 accumulatedPositionIncrease += toAdd;
296 extraRowSpanningHeight -= toAdd;
297 percent -= m_grid[row].logicalHeight.percent();
298 }
299 }
300 m_rowPos[row + 1] += accumulatedPositionIncrease;
301 }
302 }
303
304 void RenderTableSection::distributeExtraRowSpanHeightToAutoRows(RenderTableCell* cell, int totalAutoRowsHeight, int& extraRowSpanningHeight, Vector<int>& rowsHe ight)
305 {
306 if (!extraRowSpanningHeight || !totalAutoRowsHeight)
307 return;
308
309 const unsigned rowSpan = cell->rowSpan();
310 const unsigned rowIndex = cell->rowIndex();
311 int accumulatedPositionIncrease = 0;
312 int remainder = 0;
313
314 // Aspect ratios of auto rows should not change otherwise table may look dif ferent than user expected.
315 // So extra height distributed in auto spanning rows based on their weight i n spanning cell.
316 for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) {
317 if (m_grid[row].logicalHeight.isAuto()) {
318 accumulatedPositionIncrease += (extraRowSpanningHeight * rowsHeight[ row - rowIndex]) / totalAutoRowsHeight;
319 remainder += (extraRowSpanningHeight * rowsHeight[row - rowIndex]) % totalAutoRowsHeight;
320
321 // While whole extra spanning height is distributing in auto spannin g rows, rational parts remains
322 // in every integer division. So accumulating all remainder part in integer division and when total remainder
323 // is equvalent to divisor then 1 unit increased in row position.
324 // Note that this algorithm is biased towards adding more space towa rds the lower rows.
325 if (remainder >= totalAutoRowsHeight) {
326 remainder -= totalAutoRowsHeight;
327 accumulatedPositionIncrease++;
328 }
329 }
330 m_rowPos[row + 1] += accumulatedPositionIncrease;
331 }
332
333 ASSERT(!remainder);
334
335 extraRowSpanningHeight -= accumulatedPositionIncrease;
336 }
337
338 void RenderTableSection::distributeExtraRowSpanHeightToRemainingRows(RenderTable Cell* cell, int totalRemainingRowsHeight, int& extraRowSpanningHeight, Vector<in t>& rowsHeight)
339 {
340 if (!extraRowSpanningHeight || !totalRemainingRowsHeight)
341 return;
342
343 const unsigned rowSpan = cell->rowSpan();
344 const unsigned rowIndex = cell->rowIndex();
345 int accumulatedPositionIncrease = 0;
346 int remainder = 0;
347
348 // Aspect ratios of the rows should not change otherwise table may look diff erent than user expected.
349 // So extra height distribution in remaining spanning rows based on their we ight in spanning cell.
350 for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) {
351 if (!m_grid[row].logicalHeight.isPercent()) {
352 accumulatedPositionIncrease += (extraRowSpanningHeight * rowsHeight[ row - rowIndex]) / totalRemainingRowsHeight;
353 remainder += (extraRowSpanningHeight * rowsHeight[row - rowIndex]) % totalRemainingRowsHeight;
354
355 // While whole extra spanning height is distributing in remaining sp anning rows, rational parts remains
356 // in every integer division. So accumulating all remainder part in integer division and when total remainder
357 // is equvalent to divisor then 1 unit increased in row position.
358 // Note that this algorithm is biased towards adding more space towa rds the lower rows.
359 if (remainder >= totalRemainingRowsHeight) {
360 remainder -= totalRemainingRowsHeight;
361 accumulatedPositionIncrease++;
362 }
363 }
364 m_rowPos[row + 1] += accumulatedPositionIncrease;
365 }
366
367 ASSERT(!remainder);
368
369 extraRowSpanningHeight -= accumulatedPositionIncrease;
370 }
371
255 // Distribute rowSpan cell height in rows those comes in rowSpan cell based on t he ratio of row's height if 372 // Distribute rowSpan cell height in rows those comes in rowSpan cell based on t he ratio of row's height if
256 // 1. RowSpan cell height is greater then the total height of rows in rowSpan ce ll 373 // 1. RowSpan cell height is greater then the total height of rows in rowSpan ce ll
257 void RenderTableSection::distributeRowSpanHeightToRows(SpanningRenderTableCells& rowSpanCells) 374 void RenderTableSection::distributeRowSpanHeightToRows(SpanningRenderTableCells& rowSpanCells)
258 { 375 {
259 ASSERT(rowSpanCells.size()); 376 ASSERT(rowSpanCells.size());
260 377
261 // FIXME: For now, we handle the first rowspan cell in the table but this is wrong. 378 // FIXME: For now, we handle the first rowspan cell in the table but this is wrong.
262 RenderTableCell* cell = rowSpanCells[0]; 379 RenderTableCell* cell = rowSpanCells[0];
263 380
264 unsigned rowSpan = cell->rowSpan(); 381 unsigned rowSpan = cell->rowSpan();
265 unsigned rowIndex = cell->rowIndex();
266 int initialPos = m_rowPos[rowIndex + rowSpan];
267 382
268 int totalRowsHeight = 0; 383 struct SpanningRowsHeight spanningRowsHeight;
269 int rowSpanCellHeight = cell->logicalHeightForRowSizing();
270 Vector<int> rowsHeight(rowSpan);
271 384
272 // Getting height of rows in current rowSpan cell, getting total height of r ows and adjusting rowSpan cell height with border spacing. 385 populateSpanningRowsHeightFromCell(cell, spanningRowsHeight);
273 for (unsigned row = 0; row < rowSpan; row++) {
274 unsigned actualRow = row + rowIndex;
275 rowsHeight[row] = m_rowPos[actualRow + 1] - m_rowPos[actualRow] - border SpacingForRow(actualRow);
276 totalRowsHeight += rowsHeight[row];
277 rowSpanCellHeight -= borderSpacingForRow(actualRow);
278 }
279 rowSpanCellHeight += borderSpacingForRow(rowIndex + rowSpan - 1);
280 386
281 if (!totalRowsHeight || rowSpanCellHeight <= totalRowsHeight) 387 if (!spanningRowsHeight.totalRowsHeight || spanningRowsHeight.spanningCellHe ightIgnoringBorderSpacing <= spanningRowsHeight.totalRowsHeight)
282 return; 388 return;
283 389
284 // Recalculating the height of rows based on rowSpan cell height if rowSpan cell height is more than total height of rows. 390 unsigned rowIndex = cell->rowIndex();
285 int remainingHeight = rowSpanCellHeight; 391 int totalPercent = 0;
392 int totalAutoRowsHeight = 0;
393 int totalRemainingRowsHeight = spanningRowsHeight.totalRowsHeight;
286 394
395 // Calculate total percentage, total auto rows height and total rows height except percent rows.
287 for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) { 396 for (unsigned row = rowIndex; row < (rowIndex + rowSpan); row++) {
288 int rowHeight = (rowSpanCellHeight * rowsHeight[row - rowIndex]) / total RowsHeight; 397 if (m_grid[row].logicalHeight.isPercent()) {
289 remainingHeight -= rowHeight; 398 totalPercent += m_grid[row].logicalHeight.percent();
290 m_rowPos[row + 1] = m_rowPos[row] + rowHeight + borderSpacingForRow(row) ; 399 totalRemainingRowsHeight -= spanningRowsHeight.rowHeight[row - rowIn dex];
400 } else if (m_grid[row].logicalHeight.isAuto()) {
401 totalAutoRowsHeight += spanningRowsHeight.rowHeight[row - rowIndex];
402 }
291 } 403 }
292 // Remaining height added in the last row under rowSpan cell 404
293 m_rowPos[rowIndex + rowSpan] += remainingHeight; 405 int initialPos = m_rowPos[rowIndex + rowSpan];
406 int extraRowSpanningHeight = spanningRowsHeight.spanningCellHeightIgnoringBo rderSpacing - spanningRowsHeight.totalRowsHeight;
407
408 distributeExtraRowSpanHeightToPercentRows(cell, totalPercent, extraRowSpanni ngHeight, spanningRowsHeight.rowHeight);
409 distributeExtraRowSpanHeightToAutoRows(cell, totalAutoRowsHeight, extraRowSp anningHeight, spanningRowsHeight.rowHeight);
410 distributeExtraRowSpanHeightToRemainingRows(cell, totalRemainingRowsHeight, extraRowSpanningHeight, spanningRowsHeight.rowHeight);
411
412 ASSERT(!extraRowSpanningHeight);
294 413
295 // Getting total changed height in the table 414 // Getting total changed height in the table
296 unsigned changedHeight = changedHeight = m_rowPos[rowIndex + rowSpan] - init ialPos; 415 unsigned changedHeight = m_rowPos[rowIndex + rowSpan] - initialPos;
297 416
298 if (changedHeight) { 417 if (changedHeight) {
299 unsigned totalRows = m_grid.size(); 418 unsigned totalRows = m_grid.size();
300 419
301 // Apply changed height by rowSpan cells to rows present at the end of t he table 420 // Apply changed height by rowSpan cells to rows present at the end of t he table
302 for (unsigned row = rowIndex + rowSpan + 1; row <= totalRows; row++) 421 for (unsigned row = rowIndex + rowSpan + 1; row <= totalRows; row++)
303 m_rowPos[row] += changedHeight; 422 m_rowPos[row] += changedHeight;
304 } 423 }
305 } 424 }
306 425
(...skipping 1209 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 if (!style()->isLeftToRightDirection()) 1635 if (!style()->isLeftToRightDirection())
1517 cellLocation.setX(table()->columnPositions()[table()->numEffCols()] - ta ble()->columnPositions()[table()->colToEffCol(cell->col() + cell->colSpan())] + horizontalBorderSpacing); 1636 cellLocation.setX(table()->columnPositions()[table()->numEffCols()] - ta ble()->columnPositions()[table()->colToEffCol(cell->col() + cell->colSpan())] + horizontalBorderSpacing);
1518 else 1637 else
1519 cellLocation.setX(table()->columnPositions()[effectiveColumn] + horizont alBorderSpacing); 1638 cellLocation.setX(table()->columnPositions()[effectiveColumn] + horizont alBorderSpacing);
1520 1639
1521 cell->setLogicalLocation(cellLocation); 1640 cell->setLogicalLocation(cellLocation);
1522 view()->addLayoutDelta(oldCellLocation - cell->location()); 1641 view()->addLayoutDelta(oldCellLocation - cell->location());
1523 } 1642 }
1524 1643
1525 } // namespace WebCore 1644 } // namespace WebCore
OLDNEW
« LayoutTests/TestExpectations ('K') | « Source/core/rendering/RenderTableSection.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698