OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |