OLD | NEW |
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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 for (unsigned i = 0; i < numRows; i++) { | 60 for (unsigned i = 0; i < numRows; i++) { |
61 LayoutTableSection::CellStruct current = section->cellAt(i, effC
ol); | 61 LayoutTableSection::CellStruct current = section->cellAt(i, effC
ol); |
62 LayoutTableCell* cell = current.primaryCell(); | 62 LayoutTableCell* cell = current.primaryCell(); |
63 | 63 |
64 if (current.inColSpan || !cell) | 64 if (current.inColSpan || !cell) |
65 continue; | 65 continue; |
66 columnLayout.columnHasNoCells = false; | 66 columnLayout.columnHasNoCells = false; |
67 | 67 |
68 if (cell->maxPreferredLogicalWidth()) | 68 if (cell->maxPreferredLogicalWidth()) |
69 columnLayout.emptyCellsOnly = false; | 69 columnLayout.emptyCellsOnly = false; |
| 70 if (cell->colSpan() == 1) { |
70 | 71 |
71 if (cell->colSpan() == 1) { | |
72 columnLayout.minLogicalWidth = std::max<int>(cell->minPrefer
redLogicalWidth(), columnLayout.minLogicalWidth); | 72 columnLayout.minLogicalWidth = std::max<int>(cell->minPrefer
redLogicalWidth(), columnLayout.minLogicalWidth); |
73 if (cell->maxPreferredLogicalWidth() > columnLayout.maxLogic
alWidth) { | 73 if (cell->maxPreferredLogicalWidth() > columnLayout.maxLogic
alWidth) { |
74 columnLayout.maxLogicalWidth = cell->maxPreferredLogical
Width(); | 74 columnLayout.maxLogicalWidth = cell->maxPreferredLogical
Width(); |
75 maxContributor = cell; | 75 maxContributor = cell; |
76 } | 76 } |
77 | 77 |
78 // All browsers implement a size limit on the cell's max wid
th. | 78 // All browsers implement a size limit on the cell's max wid
th. |
79 // Our limit is based on KHTML's representation that used 16
bits widths. | 79 // Our limit is based on KHTML's representation that used 16
bits widths. |
80 // FIXME: Other browsers have a lower limit for the cell's m
ax width. | 80 // FIXME: Other browsers have a lower limit for the cell's m
ax width. |
81 const int cCellMaxWidth = 32760; | 81 const int cCellMaxWidth = 32760; |
(...skipping 26 matching lines...) Expand all Loading... |
108 case Percent: | 108 case Percent: |
109 m_hasPercent = true; | 109 m_hasPercent = true; |
110 // TODO(alancutter): Make this work correctly for calc l
engths. | 110 // TODO(alancutter): Make this work correctly for calc l
engths. |
111 if (cellLogicalWidth.isPositive() && (!columnLayout.logi
calWidth.hasPercent() || cellLogicalWidth.value() > columnLayout.logicalWidth.va
lue())) | 111 if (cellLogicalWidth.isPositive() && (!columnLayout.logi
calWidth.hasPercent() || cellLogicalWidth.value() > columnLayout.logicalWidth.va
lue())) |
112 columnLayout.logicalWidth = cellLogicalWidth; | 112 columnLayout.logicalWidth = cellLogicalWidth; |
113 break; | 113 break; |
114 default: | 114 default: |
115 break; | 115 break; |
116 } | 116 } |
117 } else if (!effCol || section->primaryCellAt(i, effCol - 1) != c
ell) { | 117 } else if (!effCol || section->primaryCellAt(i, effCol - 1) != c
ell) { |
118 // If a cell originates in this spanning column ensure we ha
ve a min/max width of at least 1px for it. | |
119 columnLayout.minLogicalWidth = std::max<int>(columnLayout.mi
nLogicalWidth, cell->maxPreferredLogicalWidth() ? 1 : 0); | |
120 | |
121 // This spanning cell originates in this column. Insert the
cell into spanning cells list. | 118 // This spanning cell originates in this column. Insert the
cell into spanning cells list. |
122 insertSpanCell(cell); | 119 insertSpanCell(cell); |
123 } | 120 } |
124 } | 121 } |
125 } | 122 } |
126 } | 123 } |
127 | 124 |
128 // Nav/IE weirdness | 125 // Nav/IE weirdness |
129 if (columnLayout.logicalWidth.isFixed()) { | 126 if (columnLayout.logicalWidth.isFixed()) { |
130 if (m_table->document().inQuirksMode() && columnLayout.maxLogicalWidth >
columnLayout.logicalWidth.value() && fixedContributor != maxContributor) { | 127 if (m_table->document().inQuirksMode() && columnLayout.maxLogicalWidth >
columnLayout.logicalWidth.value() && fixedContributor != maxContributor) { |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 int cellMinLogicalWidth = cell->minPreferredLogicalWidth() + spacingInRo
wDirection; | 302 int cellMinLogicalWidth = cell->minPreferredLogicalWidth() + spacingInRo
wDirection; |
306 int cellMaxLogicalWidth = cell->maxPreferredLogicalWidth() + spacingInRo
wDirection; | 303 int cellMaxLogicalWidth = cell->maxPreferredLogicalWidth() + spacingInRo
wDirection; |
307 float totalPercent = 0; | 304 float totalPercent = 0; |
308 int spanMinLogicalWidth = 0; | 305 int spanMinLogicalWidth = 0; |
309 int spanMaxLogicalWidth = 0; | 306 int spanMaxLogicalWidth = 0; |
310 bool allColsArePercent = true; | 307 bool allColsArePercent = true; |
311 bool allColsAreFixed = true; | 308 bool allColsAreFixed = true; |
312 bool haveAuto = false; | 309 bool haveAuto = false; |
313 bool spanHasEmptyCellsOnly = true; | 310 bool spanHasEmptyCellsOnly = true; |
314 int fixedWidth = 0; | 311 int fixedWidth = 0; |
| 312 int numAuto = 0; |
315 while (lastCol < nEffCols && span > 0) { | 313 while (lastCol < nEffCols && span > 0) { |
316 Layout& columnLayout = m_layoutStruct[lastCol]; | 314 Layout& columnLayout = m_layoutStruct[lastCol]; |
317 switch (columnLayout.logicalWidth.type()) { | 315 switch (columnLayout.logicalWidth.type()) { |
318 case Percent: | 316 case Percent: |
319 totalPercent += columnLayout.logicalWidth.percent(); | 317 totalPercent += columnLayout.logicalWidth.percent(); |
320 allColsAreFixed = false; | 318 allColsAreFixed = false; |
321 break; | 319 break; |
322 case Fixed: | 320 case Fixed: |
323 if (columnLayout.logicalWidth.value() > 0) { | 321 if (columnLayout.logicalWidth.value() > 0) { |
324 fixedWidth += columnLayout.logicalWidth.value(); | 322 fixedWidth += columnLayout.logicalWidth.value(); |
325 allColsArePercent = false; | 323 allColsArePercent = false; |
326 // IE resets effWidth to Auto here, but this breaks the konq
ueror about page and seems to be some bad | 324 // IE resets effWidth to Auto here, but this breaks the konq
ueror about page and seems to be some bad |
327 // legacy behaviour anyway. mozilla doesn't do this so I dec
ided we don't neither. | 325 // legacy behaviour anyway. mozilla doesn't do this so I dec
ided we don't neither. |
328 break; | 326 break; |
329 } | 327 } |
330 // fall through | 328 // fall through |
331 case Auto: | 329 case Auto: |
332 haveAuto = true; | 330 haveAuto = true; |
| 331 if (!columnLayout.columnHasNoCells) |
| 332 numAuto++; |
333 // fall through | 333 // fall through |
334 default: | 334 default: |
335 // If the column is a percentage width, do not let the spanning
cell overwrite the | 335 // If the column is a percentage width, do not let the spanning
cell overwrite the |
336 // width value. This caused a mis-layout on amazon.com. | 336 // width value. This caused a mis-layout on amazon.com. |
337 // Sample snippet: | 337 // Sample snippet: |
338 // <table border=2 width=100%>< | 338 // <table border=2 width=100%>< |
339 // <tr><td>1</td><td colspan=2>2-3</tr> | 339 // <tr><td>1</td><td colspan=2>2-3</tr> |
340 // <tr><td>1</td><td colspan=2 width=100%>2-3</td></tr> | 340 // <tr><td>1</td><td colspan=2 width=100%>2-3</td></tr> |
341 // </table> | 341 // </table> |
342 // TODO(alancutter): Make this work correctly for calc lengths. | 342 // TODO(alancutter): Make this work correctly for calc lengths. |
(...skipping 20 matching lines...) Expand all Loading... |
363 if (totalPercent > cellLogicalWidth.percent() || allColsArePercent)
{ | 363 if (totalPercent > cellLogicalWidth.percent() || allColsArePercent)
{ |
364 // can't satify this condition, treat as variable | 364 // can't satify this condition, treat as variable |
365 cellLogicalWidth = Length(); | 365 cellLogicalWidth = Length(); |
366 } else { | 366 } else { |
367 maxLogicalWidth = std::max(maxLogicalWidth, static_cast<int>(std
::max(spanMaxLogicalWidth, cellMaxLogicalWidth) * 100 / cellLogicalWidth.percen
t())); | 367 maxLogicalWidth = std::max(maxLogicalWidth, static_cast<int>(std
::max(spanMaxLogicalWidth, cellMaxLogicalWidth) * 100 / cellLogicalWidth.percen
t())); |
368 | 368 |
369 // all non percent columns in the span get percent values to sum
up correctly. | 369 // all non percent columns in the span get percent values to sum
up correctly. |
370 float percentMissing = cellLogicalWidth.percent() - totalPercent
; | 370 float percentMissing = cellLogicalWidth.percent() - totalPercent
; |
371 int totalWidth = 0; | 371 int totalWidth = 0; |
372 for (unsigned pos = effCol; pos < lastCol; ++pos) { | 372 for (unsigned pos = effCol; pos < lastCol; ++pos) { |
373 if (!m_layoutStruct[pos].effectiveLogicalWidth.hasPercent()) | 373 if (!m_layoutStruct[pos].effectiveLogicalWidth.hasPercent()
&& (!m_layoutStruct[pos].emptyCellsOnly || spanHasEmptyCellsOnly)) |
374 totalWidth += m_layoutStruct[pos].clampedEffectiveMaxLog
icalWidth(); | 374 totalWidth += m_layoutStruct[pos].clampedEffectiveMaxLog
icalWidth(); |
375 } | 375 } |
376 | 376 |
377 for (unsigned pos = effCol; pos < lastCol && totalWidth > 0; ++p
os) { | 377 for (unsigned pos = effCol; pos < lastCol && totalWidth > 0; ++p
os) { |
378 if (!m_layoutStruct[pos].effectiveLogicalWidth.hasPercent())
{ | 378 // Empty columns shouldn't get any share of a span's percent
width. |
379 float percent = percentMissing * static_cast<float>(m_la
youtStruct[pos].effectiveMaxLogicalWidth) / totalWidth; | 379 if (!m_layoutStruct[pos].effectiveLogicalWidth.hasPercent()
&& (!m_layoutStruct[pos].emptyCellsOnly || spanHasEmptyCellsOnly)) { |
| 380 float percent = percentMissing * static_cast<float>(m_la
youtStruct[pos].clampedEffectiveMaxLogicalWidth()) / totalWidth; |
380 totalWidth -= m_layoutStruct[pos].clampedEffectiveMaxLog
icalWidth(); | 381 totalWidth -= m_layoutStruct[pos].clampedEffectiveMaxLog
icalWidth(); |
381 percentMissing -= percent; | 382 percentMissing -= percent; |
382 if (percent > 0) | 383 if (percent > 0 && !m_layoutStruct[pos].columnHasNoCells
) |
383 m_layoutStruct[pos].effectiveLogicalWidth.setValue(P
ercent, percent); | 384 m_layoutStruct[pos].effectiveLogicalWidth.setValue(P
ercent, percent); |
384 else | 385 else |
385 m_layoutStruct[pos].effectiveLogicalWidth = Length()
; | 386 m_layoutStruct[pos].effectiveLogicalWidth = Length()
; |
386 } | 387 } |
387 } | 388 } |
388 } | 389 } |
389 } | 390 } |
390 | 391 |
391 // make sure minWidth and maxWidth of the spanning cell are honoured | 392 // make sure minWidth and maxWidth of the spanning cell are honoured |
392 if (cellMinLogicalWidth > spanMinLogicalWidth) { | 393 if (cellMinLogicalWidth > spanMinLogicalWidth) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiv
eMaxLogicalWidth; | 441 remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiv
eMaxLogicalWidth; |
441 remainingMinLogicalWidth -= m_layoutStruct[pos].effectiv
eMinLogicalWidth; | 442 remainingMinLogicalWidth -= m_layoutStruct[pos].effectiv
eMinLogicalWidth; |
442 cellMinLogicalWidth -= colMinLogicalWidth; | 443 cellMinLogicalWidth -= colMinLogicalWidth; |
443 m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLog
icalWidth; | 444 m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLog
icalWidth; |
444 } | 445 } |
445 } | 446 } |
446 } | 447 } |
447 } | 448 } |
448 if (!cellLogicalWidth.hasPercent()) { | 449 if (!cellLogicalWidth.hasPercent()) { |
449 if (cellMaxLogicalWidth > spanMaxLogicalWidth) { | 450 if (cellMaxLogicalWidth > spanMaxLogicalWidth) { |
| 451 int widthAvailableToAuto = cellMaxLogicalWidth - fixedWidth; |
450 for (unsigned pos = effCol; spanMaxLogicalWidth >= 0 && pos < la
stCol; ++pos) { | 452 for (unsigned pos = effCol; spanMaxLogicalWidth >= 0 && pos < la
stCol; ++pos) { |
451 int colMaxLogicalWidth = std::max(m_layoutStruct[pos].effect
iveMaxLogicalWidth, static_cast<int>(spanMaxLogicalWidth ? cellMaxLogicalWidth *
static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / spanMaxLogic
alWidth : cellMaxLogicalWidth)); | 453 int colMaxLogicalWidth = std::max(m_layoutStruct[pos].effect
iveMaxLogicalWidth, static_cast<int>(spanMaxLogicalWidth ? cellMaxLogicalWidth *
static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / spanMaxLogic
alWidth : cellMaxLogicalWidth)); |
452 spanMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogic
alWidth; | 454 spanMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogic
alWidth; |
453 cellMaxLogicalWidth -= colMaxLogicalWidth; | 455 cellMaxLogicalWidth -= colMaxLogicalWidth; |
454 m_layoutStruct[pos].effectiveMaxLogicalWidth = colMaxLogical
Width; | 456 m_layoutStruct[pos].effectiveMaxLogicalWidth = colMaxLogical
Width; |
| 457 if (m_layoutStruct[pos].logicalWidth.isAuto() && m_layoutStr
uct[pos].emptyCellsOnly && !m_layoutStruct[pos].columnHasNoCells && !spanHasEmpt
yCellsOnly) |
| 458 m_layoutStruct[pos].effectiveMinLogicalWidth = widthAvai
lableToAuto / numAuto; |
455 } | 459 } |
456 } | 460 } |
457 } else { | 461 } else { |
458 for (unsigned pos = effCol; pos < lastCol; ++pos) | 462 for (unsigned pos = effCol; pos < lastCol; ++pos) |
459 m_layoutStruct[pos].maxLogicalWidth = std::max(m_layoutStruct[po
s].maxLogicalWidth, m_layoutStruct[pos].minLogicalWidth); | 463 m_layoutStruct[pos].maxLogicalWidth = std::max(m_layoutStruct[po
s].maxLogicalWidth, m_layoutStruct[pos].minLogicalWidth); |
460 } | 464 } |
461 // treat span ranges consisting of empty cells only as if they had conte
nt | 465 // treat span ranges consisting of empty cells only as if they had conte
nt |
462 if (spanHasEmptyCellsOnly) { | 466 if (spanHasEmptyCellsOnly) { |
463 for (unsigned pos = effCol; pos < lastCol; ++pos) | 467 for (unsigned pos = effCol; pos < lastCol; ++pos) |
464 m_layoutStruct[pos].emptyCellsOnly = false; | 468 m_layoutStruct[pos].emptyCellsOnly = false; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 havePercent = true; | 538 havePercent = true; |
535 totalPercent += logicalWidth.percent(); | 539 totalPercent += logicalWidth.percent(); |
536 break; | 540 break; |
537 case Fixed: | 541 case Fixed: |
538 numFixed++; | 542 numFixed++; |
539 totalFixed += m_layoutStruct[i].clampedEffectiveMaxLogicalWidth(); | 543 totalFixed += m_layoutStruct[i].clampedEffectiveMaxLogicalWidth(); |
540 // fall through | 544 // fall through |
541 break; | 545 break; |
542 case Auto: | 546 case Auto: |
543 if (m_layoutStruct[i].emptyCellsOnly) { | 547 if (m_layoutStruct[i].emptyCellsOnly) { |
544 numAutoEmptyCellsOnly++; | 548 if (!m_layoutStruct[i].columnHasNoCells) |
| 549 numAutoEmptyCellsOnly++; |
545 } else { | 550 } else { |
546 numAuto++; | 551 numAuto++; |
547 totalAuto += m_layoutStruct[i].clampedEffectiveMaxLogicalWidth()
; | 552 totalAuto += m_layoutStruct[i].clampedEffectiveMaxLogicalWidth()
; |
548 } | 553 } |
549 if (!m_layoutStruct[i].columnHasNoCells) | 554 if (!m_layoutStruct[i].columnHasNoCells) |
550 allocAuto += cellLogicalWidth; | 555 allocAuto += cellLogicalWidth; |
551 break; | 556 break; |
552 default: | 557 default: |
553 break; | 558 break; |
554 } | 559 } |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
692 int reduce = available * minMaxDiff / logicalWidthBeyondMin; | 697 int reduce = available * minMaxDiff / logicalWidthBeyondMin; |
693 m_layoutStruct[i].computedLogicalWidth += reduce; | 698 m_layoutStruct[i].computedLogicalWidth += reduce; |
694 available -= reduce; | 699 available -= reduce; |
695 logicalWidthBeyondMin -= minMaxDiff; | 700 logicalWidthBeyondMin -= minMaxDiff; |
696 if (available >= 0) | 701 if (available >= 0) |
697 break; | 702 break; |
698 } | 703 } |
699 } | 704 } |
700 } | 705 } |
701 } | 706 } |
OLD | NEW |