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 10 matching lines...) Expand all Loading... |
21 | 21 |
22 #include "config.h" | 22 #include "config.h" |
23 #include "core/rendering/AutoTableLayout.h" | 23 #include "core/rendering/AutoTableLayout.h" |
24 | 24 |
25 #include "core/rendering/FastTextAutosizer.h" | 25 #include "core/rendering/FastTextAutosizer.h" |
26 #include "core/rendering/RenderTable.h" | 26 #include "core/rendering/RenderTable.h" |
27 #include "core/rendering/RenderTableCell.h" | 27 #include "core/rendering/RenderTableCell.h" |
28 #include "core/rendering/RenderTableCol.h" | 28 #include "core/rendering/RenderTableCol.h" |
29 #include "core/rendering/RenderTableSection.h" | 29 #include "core/rendering/RenderTableSection.h" |
30 | 30 |
31 using namespace std; | |
32 | |
33 namespace WebCore { | 31 namespace WebCore { |
34 | 32 |
35 AutoTableLayout::AutoTableLayout(RenderTable* table) | 33 AutoTableLayout::AutoTableLayout(RenderTable* table) |
36 : TableLayout(table) | 34 : TableLayout(table) |
37 , m_hasPercent(false) | 35 , m_hasPercent(false) |
38 , m_effectiveLogicalWidthDirty(true) | 36 , m_effectiveLogicalWidthDirty(true) |
39 { | 37 { |
40 } | 38 } |
41 | 39 |
42 AutoTableLayout::~AutoTableLayout() | 40 AutoTableLayout::~AutoTableLayout() |
(...skipping 22 matching lines...) Expand all Loading... |
65 | 63 |
66 if (current.inColSpan || !cell) | 64 if (current.inColSpan || !cell) |
67 continue; | 65 continue; |
68 | 66 |
69 bool cellHasContent = cell->children()->firstChild() || cell->st
yle()->hasBorder() || cell->style()->hasPadding() || cell->style()->hasBackgroun
d(); | 67 bool cellHasContent = cell->children()->firstChild() || cell->st
yle()->hasBorder() || cell->style()->hasPadding() || cell->style()->hasBackgroun
d(); |
70 if (cellHasContent) | 68 if (cellHasContent) |
71 columnLayout.emptyCellsOnly = false; | 69 columnLayout.emptyCellsOnly = false; |
72 | 70 |
73 // A cell originates in this column. Ensure we have | 71 // A cell originates in this column. Ensure we have |
74 // a min/max width of at least 1px for this column now. | 72 // a min/max width of at least 1px for this column now. |
75 columnLayout.minLogicalWidth = max<int>(columnLayout.minLogicalW
idth, cellHasContent ? 1 : 0); | 73 columnLayout.minLogicalWidth = std::max<int>(columnLayout.minLog
icalWidth, cellHasContent ? 1 : 0); |
76 columnLayout.maxLogicalWidth = max<int>(columnLayout.maxLogicalW
idth, 1); | 74 columnLayout.maxLogicalWidth = std::max<int>(columnLayout.maxLog
icalWidth, 1); |
77 | 75 |
78 if (cell->colSpan() == 1) { | 76 if (cell->colSpan() == 1) { |
79 columnLayout.minLogicalWidth = max<int>(cell->minPreferredLo
gicalWidth(), columnLayout.minLogicalWidth); | 77 columnLayout.minLogicalWidth = std::max<int>(cell->minPrefer
redLogicalWidth(), columnLayout.minLogicalWidth); |
80 if (cell->maxPreferredLogicalWidth() > columnLayout.maxLogic
alWidth) { | 78 if (cell->maxPreferredLogicalWidth() > columnLayout.maxLogic
alWidth) { |
81 columnLayout.maxLogicalWidth = cell->maxPreferredLogical
Width(); | 79 columnLayout.maxLogicalWidth = cell->maxPreferredLogical
Width(); |
82 maxContributor = cell; | 80 maxContributor = cell; |
83 } | 81 } |
84 | 82 |
85 // All browsers implement a size limit on the cell's max wid
th. | 83 // All browsers implement a size limit on the cell's max wid
th. |
86 // Our limit is based on KHTML's representation that used 16
bits widths. | 84 // Our limit is based on KHTML's representation that used 16
bits widths. |
87 // FIXME: Other browsers have a lower limit for the cell's m
ax width. | 85 // FIXME: Other browsers have a lower limit for the cell's m
ax width. |
88 const int cCellMaxWidth = 32760; | 86 const int cCellMaxWidth = 32760; |
89 Length cellLogicalWidth = cell->styleOrColLogicalWidth(); | 87 Length cellLogicalWidth = cell->styleOrColLogicalWidth(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 } | 124 } |
127 | 125 |
128 // Nav/IE weirdness | 126 // Nav/IE weirdness |
129 if (columnLayout.logicalWidth.isFixed()) { | 127 if (columnLayout.logicalWidth.isFixed()) { |
130 if (m_table->document().inQuirksMode() && columnLayout.maxLogicalWidth >
columnLayout.logicalWidth.value() && fixedContributor != maxContributor) { | 128 if (m_table->document().inQuirksMode() && columnLayout.maxLogicalWidth >
columnLayout.logicalWidth.value() && fixedContributor != maxContributor) { |
131 columnLayout.logicalWidth = Length(); | 129 columnLayout.logicalWidth = Length(); |
132 fixedContributor = 0; | 130 fixedContributor = 0; |
133 } | 131 } |
134 } | 132 } |
135 | 133 |
136 columnLayout.maxLogicalWidth = max(columnLayout.maxLogicalWidth, columnLayou
t.minLogicalWidth); | 134 columnLayout.maxLogicalWidth = std::max(columnLayout.maxLogicalWidth, column
Layout.minLogicalWidth); |
137 } | 135 } |
138 | 136 |
139 void AutoTableLayout::fullRecalc() | 137 void AutoTableLayout::fullRecalc() |
140 { | 138 { |
141 m_hasPercent = false; | 139 m_hasPercent = false; |
142 m_effectiveLogicalWidthDirty = true; | 140 m_effectiveLogicalWidthDirty = true; |
143 | 141 |
144 unsigned nEffCols = m_table->numEffCols(); | 142 unsigned nEffCols = m_table->numEffCols(); |
145 m_layoutStruct.resize(nEffCols); | 143 m_layoutStruct.resize(nEffCols); |
146 m_layoutStruct.fill(Layout()); | 144 m_layoutStruct.fill(Layout()); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 // We substitute 0 percent by (epsilon / percentScaleFactor) percent in two
places below to avoid division by zero. | 220 // We substitute 0 percent by (epsilon / percentScaleFactor) percent in two
places below to avoid division by zero. |
223 // FIXME: Handle the 0% cases properly. | 221 // FIXME: Handle the 0% cases properly. |
224 const float epsilon = 1 / 128.0f; | 222 const float epsilon = 1 / 128.0f; |
225 | 223 |
226 float remainingPercent = 100; | 224 float remainingPercent = 100; |
227 for (size_t i = 0; i < m_layoutStruct.size(); ++i) { | 225 for (size_t i = 0; i < m_layoutStruct.size(); ++i) { |
228 minWidth += m_layoutStruct[i].effectiveMinLogicalWidth; | 226 minWidth += m_layoutStruct[i].effectiveMinLogicalWidth; |
229 maxWidth += m_layoutStruct[i].effectiveMaxLogicalWidth; | 227 maxWidth += m_layoutStruct[i].effectiveMaxLogicalWidth; |
230 if (scaleColumns) { | 228 if (scaleColumns) { |
231 if (m_layoutStruct[i].effectiveLogicalWidth.isPercent()) { | 229 if (m_layoutStruct[i].effectiveLogicalWidth.isPercent()) { |
232 float percent = min(static_cast<float>(m_layoutStruct[i].effecti
veLogicalWidth.percent()), remainingPercent); | 230 float percent = std::min(static_cast<float>(m_layoutStruct[i].ef
fectiveLogicalWidth.percent()), remainingPercent); |
233 float logicalWidth = static_cast<float>(m_layoutStruct[i].effect
iveMaxLogicalWidth) * 100 / max(percent, epsilon); | 231 float logicalWidth = static_cast<float>(m_layoutStruct[i].effect
iveMaxLogicalWidth) * 100 / std::max(percent, epsilon); |
234 maxPercent = max(logicalWidth, maxPercent); | 232 maxPercent = std::max(logicalWidth, maxPercent); |
235 remainingPercent -= percent; | 233 remainingPercent -= percent; |
236 } else | 234 } else |
237 maxNonPercent += m_layoutStruct[i].effectiveMaxLogicalWidth; | 235 maxNonPercent += m_layoutStruct[i].effectiveMaxLogicalWidth; |
238 } | 236 } |
239 } | 237 } |
240 | 238 |
241 if (scaleColumns) { | 239 if (scaleColumns) { |
242 maxNonPercent = maxNonPercent * 100 / max(remainingPercent, epsilon); | 240 maxNonPercent = maxNonPercent * 100 / std::max(remainingPercent, epsilon
); |
243 maxWidth = max<int>(maxWidth, static_cast<int>(min(maxNonPercent, static
_cast<float>(tableMaxWidth)))); | 241 maxWidth = std::max<int>(maxWidth, static_cast<int>(std::min(maxNonPerce
nt, static_cast<float>(tableMaxWidth)))); |
244 maxWidth = max<int>(maxWidth, static_cast<int>(min(maxPercent, static_ca
st<float>(tableMaxWidth)))); | 242 maxWidth = std::max<int>(maxWidth, static_cast<int>(std::min(maxPercent,
static_cast<float>(tableMaxWidth)))); |
245 } | 243 } |
246 | 244 |
247 maxWidth = max<int>(maxWidth, spanMaxLogicalWidth); | 245 maxWidth = std::max<int>(maxWidth, spanMaxLogicalWidth); |
248 } | 246 } |
249 | 247 |
250 void AutoTableLayout::applyPreferredLogicalWidthQuirks(LayoutUnit& minWidth, Lay
outUnit& maxWidth) const | 248 void AutoTableLayout::applyPreferredLogicalWidthQuirks(LayoutUnit& minWidth, Lay
outUnit& maxWidth) const |
251 { | 249 { |
252 Length tableLogicalWidth = m_table->style()->logicalWidth(); | 250 Length tableLogicalWidth = m_table->style()->logicalWidth(); |
253 if (tableLogicalWidth.isFixed() && tableLogicalWidth.isPositive()) { | 251 if (tableLogicalWidth.isFixed() && tableLogicalWidth.isPositive()) { |
254 // |minWidth| is the result of measuring the intrinsic content's size. K
eep it to | 252 // |minWidth| is the result of measuring the intrinsic content's size. K
eep it to |
255 // make sure we are *never* smaller than the actual content. | 253 // make sure we are *never* smaller than the actual content. |
256 LayoutUnit minContentWidth = minWidth; | 254 LayoutUnit minContentWidth = minWidth; |
257 // FIXME: This line looks REALLY suspicious as it could allow the minimu
m | 255 // FIXME: This line looks REALLY suspicious as it could allow the minimu
m |
258 // preferred logical width to be smaller than the table content. This ha
s | 256 // preferred logical width to be smaller than the table content. This ha
s |
259 // to be cross-checked against other browsers. | 257 // to be cross-checked against other browsers. |
260 minWidth = maxWidth = max<int>(minWidth, tableLogicalWidth.value()); | 258 minWidth = maxWidth = std::max<int>(minWidth, tableLogicalWidth.value())
; |
261 | 259 |
262 const Length& styleMaxLogicalWidth = m_table->style()->logicalMaxWidth()
; | 260 const Length& styleMaxLogicalWidth = m_table->style()->logicalMaxWidth()
; |
263 if (styleMaxLogicalWidth.isFixed() && !styleMaxLogicalWidth.isNegative()
) { | 261 if (styleMaxLogicalWidth.isFixed() && !styleMaxLogicalWidth.isNegative()
) { |
264 minWidth = min<int>(minWidth, styleMaxLogicalWidth.value()); | 262 minWidth = std::min<int>(minWidth, styleMaxLogicalWidth.value()); |
265 minWidth = max(minWidth, minContentWidth); | 263 minWidth = std::max(minWidth, minContentWidth); |
266 maxWidth = minWidth; | 264 maxWidth = minWidth; |
267 } | 265 } |
268 } | 266 } |
269 } | 267 } |
270 | 268 |
271 /* | 269 /* |
272 This method takes care of colspans. | 270 This method takes care of colspans. |
273 effWidth is the same as width for cells without colspans. If we have colspans,
they get modified. | 271 effWidth is the same as width for cells without colspans. If we have colspans,
they get modified. |
274 */ | 272 */ |
275 int AutoTableLayout::calcEffectiveLogicalWidth() | 273 int AutoTableLayout::calcEffectiveLogicalWidth() |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 cellMinLogicalWidth -= spacingInRowDirection; | 349 cellMinLogicalWidth -= spacingInRowDirection; |
352 cellMaxLogicalWidth -= spacingInRowDirection; | 350 cellMaxLogicalWidth -= spacingInRowDirection; |
353 } | 351 } |
354 | 352 |
355 // adjust table max width if needed | 353 // adjust table max width if needed |
356 if (cellLogicalWidth.isPercent()) { | 354 if (cellLogicalWidth.isPercent()) { |
357 if (totalPercent > cellLogicalWidth.percent() || allColsArePercent)
{ | 355 if (totalPercent > cellLogicalWidth.percent() || allColsArePercent)
{ |
358 // can't satify this condition, treat as variable | 356 // can't satify this condition, treat as variable |
359 cellLogicalWidth = Length(); | 357 cellLogicalWidth = Length(); |
360 } else { | 358 } else { |
361 maxLogicalWidth = max(maxLogicalWidth, static_cast<int>(max(span
MaxLogicalWidth, cellMaxLogicalWidth) * 100 / cellLogicalWidth.percent())); | 359 maxLogicalWidth = std::max(maxLogicalWidth, static_cast<int>(std
::max(spanMaxLogicalWidth, cellMaxLogicalWidth) * 100 / cellLogicalWidth.percen
t())); |
362 | 360 |
363 // all non percent columns in the span get percent values to sum
up correctly. | 361 // all non percent columns in the span get percent values to sum
up correctly. |
364 float percentMissing = cellLogicalWidth.percent() - totalPercent
; | 362 float percentMissing = cellLogicalWidth.percent() - totalPercent
; |
365 int totalWidth = 0; | 363 int totalWidth = 0; |
366 for (unsigned pos = effCol; pos < lastCol; ++pos) { | 364 for (unsigned pos = effCol; pos < lastCol; ++pos) { |
367 if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercent()) | 365 if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercent()) |
368 totalWidth += m_layoutStruct[pos].effectiveMaxLogicalWid
th; | 366 totalWidth += m_layoutStruct[pos].effectiveMaxLogicalWid
th; |
369 } | 367 } |
370 | 368 |
371 for (unsigned pos = effCol; pos < lastCol && totalWidth > 0; ++p
os) { | 369 for (unsigned pos = effCol; pos < lastCol && totalWidth > 0; ++p
os) { |
372 if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercent())
{ | 370 if (!m_layoutStruct[pos].effectiveLogicalWidth.isPercent())
{ |
373 float percent = percentMissing * static_cast<float>(m_la
youtStruct[pos].effectiveMaxLogicalWidth) / totalWidth; | 371 float percent = percentMissing * static_cast<float>(m_la
youtStruct[pos].effectiveMaxLogicalWidth) / totalWidth; |
374 totalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWid
th; | 372 totalWidth -= m_layoutStruct[pos].effectiveMaxLogicalWid
th; |
375 percentMissing -= percent; | 373 percentMissing -= percent; |
376 if (percent > 0) | 374 if (percent > 0) |
377 m_layoutStruct[pos].effectiveLogicalWidth.setValue(P
ercent, percent); | 375 m_layoutStruct[pos].effectiveLogicalWidth.setValue(P
ercent, percent); |
378 else | 376 else |
379 m_layoutStruct[pos].effectiveLogicalWidth = Length()
; | 377 m_layoutStruct[pos].effectiveLogicalWidth = Length()
; |
380 } | 378 } |
381 } | 379 } |
382 } | 380 } |
383 } | 381 } |
384 | 382 |
385 // make sure minWidth and maxWidth of the spanning cell are honoured | 383 // make sure minWidth and maxWidth of the spanning cell are honoured |
386 if (cellMinLogicalWidth > spanMinLogicalWidth) { | 384 if (cellMinLogicalWidth > spanMinLogicalWidth) { |
387 if (allColsAreFixed) { | 385 if (allColsAreFixed) { |
388 for (unsigned pos = effCol; fixedWidth > 0 && pos < lastCol; ++p
os) { | 386 for (unsigned pos = effCol; fixedWidth > 0 && pos < lastCol; ++p
os) { |
389 int cellLogicalWidth = max(m_layoutStruct[pos].effectiveMinL
ogicalWidth, static_cast<int>(cellMinLogicalWidth * m_layoutStruct[pos].logicalW
idth.value() / fixedWidth)); | 387 int cellLogicalWidth = std::max(m_layoutStruct[pos].effectiv
eMinLogicalWidth, static_cast<int>(cellMinLogicalWidth * m_layoutStruct[pos].log
icalWidth.value() / fixedWidth)); |
390 fixedWidth -= m_layoutStruct[pos].logicalWidth.value(); | 388 fixedWidth -= m_layoutStruct[pos].logicalWidth.value(); |
391 cellMinLogicalWidth -= cellLogicalWidth; | 389 cellMinLogicalWidth -= cellLogicalWidth; |
392 m_layoutStruct[pos].effectiveMinLogicalWidth = cellLogicalWi
dth; | 390 m_layoutStruct[pos].effectiveMinLogicalWidth = cellLogicalWi
dth; |
393 } | 391 } |
394 } else if (allColsArePercent) { | 392 } else if (allColsArePercent) { |
395 // In this case, we just split the colspan's min amd max widths
following the percentage. | 393 // In this case, we just split the colspan's min amd max widths
following the percentage. |
396 int allocatedMinLogicalWidth = 0; | 394 int allocatedMinLogicalWidth = 0; |
397 int allocatedMaxLogicalWidth = 0; | 395 int allocatedMaxLogicalWidth = 0; |
398 for (unsigned pos = effCol; pos < lastCol; ++pos) { | 396 for (unsigned pos = effCol; pos < lastCol; ++pos) { |
399 ASSERT(m_layoutStruct[pos].logicalWidth.isPercent() || m_lay
outStruct[pos].effectiveLogicalWidth.isPercent()); | 397 ASSERT(m_layoutStruct[pos].logicalWidth.isPercent() || m_lay
outStruct[pos].effectiveLogicalWidth.isPercent()); |
400 // |allColsArePercent| means that either the logicalWidth *o
r* the effectiveLogicalWidth are percents, handle both of them here. | 398 // |allColsArePercent| means that either the logicalWidth *o
r* the effectiveLogicalWidth are percents, handle both of them here. |
401 float percent = m_layoutStruct[pos].logicalWidth.isPercent()
? m_layoutStruct[pos].logicalWidth.percent() : m_layoutStruct[pos].effectiveLog
icalWidth.percent(); | 399 float percent = m_layoutStruct[pos].logicalWidth.isPercent()
? m_layoutStruct[pos].logicalWidth.percent() : m_layoutStruct[pos].effectiveLog
icalWidth.percent(); |
402 int columnMinLogicalWidth = static_cast<int>(percent * cellM
inLogicalWidth / totalPercent); | 400 int columnMinLogicalWidth = static_cast<int>(percent * cellM
inLogicalWidth / totalPercent); |
403 int columnMaxLogicalWidth = static_cast<int>(percent * cellM
axLogicalWidth / totalPercent); | 401 int columnMaxLogicalWidth = static_cast<int>(percent * cellM
axLogicalWidth / totalPercent); |
404 m_layoutStruct[pos].effectiveMinLogicalWidth = max(m_layoutS
truct[pos].effectiveMinLogicalWidth, columnMinLogicalWidth); | 402 m_layoutStruct[pos].effectiveMinLogicalWidth = std::max(m_la
youtStruct[pos].effectiveMinLogicalWidth, columnMinLogicalWidth); |
405 m_layoutStruct[pos].effectiveMaxLogicalWidth = columnMaxLogi
calWidth; | 403 m_layoutStruct[pos].effectiveMaxLogicalWidth = columnMaxLogi
calWidth; |
406 allocatedMinLogicalWidth += columnMinLogicalWidth; | 404 allocatedMinLogicalWidth += columnMinLogicalWidth; |
407 allocatedMaxLogicalWidth += columnMaxLogicalWidth; | 405 allocatedMaxLogicalWidth += columnMaxLogicalWidth; |
408 } | 406 } |
409 ASSERT(allocatedMinLogicalWidth <= cellMinLogicalWidth); | 407 ASSERT(allocatedMinLogicalWidth <= cellMinLogicalWidth); |
410 ASSERT(allocatedMaxLogicalWidth <= cellMaxLogicalWidth); | 408 ASSERT(allocatedMaxLogicalWidth <= cellMaxLogicalWidth); |
411 cellMinLogicalWidth -= allocatedMinLogicalWidth; | 409 cellMinLogicalWidth -= allocatedMinLogicalWidth; |
412 cellMaxLogicalWidth -= allocatedMaxLogicalWidth; | 410 cellMaxLogicalWidth -= allocatedMaxLogicalWidth; |
413 } else { | 411 } else { |
414 int remainingMaxLogicalWidth = spanMaxLogicalWidth; | 412 int remainingMaxLogicalWidth = spanMaxLogicalWidth; |
415 int remainingMinLogicalWidth = spanMinLogicalWidth; | 413 int remainingMinLogicalWidth = spanMinLogicalWidth; |
416 | 414 |
417 // Give min to variable first, to fixed second, and to others th
ird. | 415 // Give min to variable first, to fixed second, and to others th
ird. |
418 for (unsigned pos = effCol; remainingMaxLogicalWidth >= 0 && pos
< lastCol; ++pos) { | 416 for (unsigned pos = effCol; remainingMaxLogicalWidth >= 0 && pos
< lastCol; ++pos) { |
419 if (m_layoutStruct[pos].logicalWidth.isFixed() && haveAuto &
& fixedWidth <= cellMinLogicalWidth) { | 417 if (m_layoutStruct[pos].logicalWidth.isFixed() && haveAuto &
& fixedWidth <= cellMinLogicalWidth) { |
420 int colMinLogicalWidth = max<int>(m_layoutStruct[pos].ef
fectiveMinLogicalWidth, m_layoutStruct[pos].logicalWidth.value()); | 418 int colMinLogicalWidth = std::max<int>(m_layoutStruct[po
s].effectiveMinLogicalWidth, m_layoutStruct[pos].logicalWidth.value()); |
421 fixedWidth -= m_layoutStruct[pos].logicalWidth.value(); | 419 fixedWidth -= m_layoutStruct[pos].logicalWidth.value(); |
422 remainingMinLogicalWidth -= m_layoutStruct[pos].effectiv
eMinLogicalWidth; | 420 remainingMinLogicalWidth -= m_layoutStruct[pos].effectiv
eMinLogicalWidth; |
423 remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiv
eMaxLogicalWidth; | 421 remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiv
eMaxLogicalWidth; |
424 cellMinLogicalWidth -= colMinLogicalWidth; | 422 cellMinLogicalWidth -= colMinLogicalWidth; |
425 m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLog
icalWidth; | 423 m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLog
icalWidth; |
426 } | 424 } |
427 } | 425 } |
428 | 426 |
429 for (unsigned pos = effCol; remainingMaxLogicalWidth >= 0 && pos
< lastCol && remainingMinLogicalWidth < cellMinLogicalWidth; ++pos) { | 427 for (unsigned pos = effCol; remainingMaxLogicalWidth >= 0 && pos
< lastCol && remainingMinLogicalWidth < cellMinLogicalWidth; ++pos) { |
430 if (!(m_layoutStruct[pos].logicalWidth.isFixed() && haveAuto
&& fixedWidth <= cellMinLogicalWidth)) { | 428 if (!(m_layoutStruct[pos].logicalWidth.isFixed() && haveAuto
&& fixedWidth <= cellMinLogicalWidth)) { |
431 int colMinLogicalWidth = max<int>(m_layoutStruct[pos].ef
fectiveMinLogicalWidth, static_cast<int>(remainingMaxLogicalWidth ? cellMinLogic
alWidth * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / rem
ainingMaxLogicalWidth : cellMinLogicalWidth)); | 429 int colMinLogicalWidth = std::max<int>(m_layoutStruct[po
s].effectiveMinLogicalWidth, static_cast<int>(remainingMaxLogicalWidth ? cellMin
LogicalWidth * static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth)
/ remainingMaxLogicalWidth : cellMinLogicalWidth)); |
432 colMinLogicalWidth = min<int>(m_layoutStruct[pos].effect
iveMinLogicalWidth + (cellMinLogicalWidth - remainingMinLogicalWidth), colMinLog
icalWidth); | 430 colMinLogicalWidth = std::min<int>(m_layoutStruct[pos].e
ffectiveMinLogicalWidth + (cellMinLogicalWidth - remainingMinLogicalWidth), colM
inLogicalWidth); |
433 remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiv
eMaxLogicalWidth; | 431 remainingMaxLogicalWidth -= m_layoutStruct[pos].effectiv
eMaxLogicalWidth; |
434 remainingMinLogicalWidth -= m_layoutStruct[pos].effectiv
eMinLogicalWidth; | 432 remainingMinLogicalWidth -= m_layoutStruct[pos].effectiv
eMinLogicalWidth; |
435 cellMinLogicalWidth -= colMinLogicalWidth; | 433 cellMinLogicalWidth -= colMinLogicalWidth; |
436 m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLog
icalWidth; | 434 m_layoutStruct[pos].effectiveMinLogicalWidth = colMinLog
icalWidth; |
437 } | 435 } |
438 } | 436 } |
439 } | 437 } |
440 } | 438 } |
441 if (!cellLogicalWidth.isPercent()) { | 439 if (!cellLogicalWidth.isPercent()) { |
442 if (cellMaxLogicalWidth > spanMaxLogicalWidth) { | 440 if (cellMaxLogicalWidth > spanMaxLogicalWidth) { |
443 for (unsigned pos = effCol; spanMaxLogicalWidth >= 0 && pos < la
stCol; ++pos) { | 441 for (unsigned pos = effCol; spanMaxLogicalWidth >= 0 && pos < la
stCol; ++pos) { |
444 int colMaxLogicalWidth = max(m_layoutStruct[pos].effectiveMa
xLogicalWidth, static_cast<int>(spanMaxLogicalWidth ? cellMaxLogicalWidth * stat
ic_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / spanMaxLogicalWid
th : cellMaxLogicalWidth)); | 442 int colMaxLogicalWidth = std::max(m_layoutStruct[pos].effect
iveMaxLogicalWidth, static_cast<int>(spanMaxLogicalWidth ? cellMaxLogicalWidth *
static_cast<float>(m_layoutStruct[pos].effectiveMaxLogicalWidth) / spanMaxLogic
alWidth : cellMaxLogicalWidth)); |
445 spanMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogic
alWidth; | 443 spanMaxLogicalWidth -= m_layoutStruct[pos].effectiveMaxLogic
alWidth; |
446 cellMaxLogicalWidth -= colMaxLogicalWidth; | 444 cellMaxLogicalWidth -= colMaxLogicalWidth; |
447 m_layoutStruct[pos].effectiveMaxLogicalWidth = colMaxLogical
Width; | 445 m_layoutStruct[pos].effectiveMaxLogicalWidth = colMaxLogical
Width; |
448 } | 446 } |
449 } | 447 } |
450 } else { | 448 } else { |
451 for (unsigned pos = effCol; pos < lastCol; ++pos) | 449 for (unsigned pos = effCol; pos < lastCol; ++pos) |
452 m_layoutStruct[pos].maxLogicalWidth = max(m_layoutStruct[pos].ma
xLogicalWidth, m_layoutStruct[pos].minLogicalWidth); | 450 m_layoutStruct[pos].maxLogicalWidth = std::max(m_layoutStruct[po
s].maxLogicalWidth, m_layoutStruct[pos].minLogicalWidth); |
453 } | 451 } |
454 // treat span ranges consisting of empty cells only as if they had conte
nt | 452 // treat span ranges consisting of empty cells only as if they had conte
nt |
455 if (spanHasEmptyCellsOnly) { | 453 if (spanHasEmptyCellsOnly) { |
456 for (unsigned pos = effCol; pos < lastCol; ++pos) | 454 for (unsigned pos = effCol; pos < lastCol; ++pos) |
457 m_layoutStruct[pos].emptyCellsOnly = false; | 455 m_layoutStruct[pos].emptyCellsOnly = false; |
458 } | 456 } |
459 } | 457 } |
460 m_effectiveLogicalWidthDirty = false; | 458 m_effectiveLogicalWidthDirty = false; |
461 | 459 |
462 return min(maxLogicalWidth, INT_MAX / 2); | 460 return std::min(maxLogicalWidth, INT_MAX / 2); |
463 } | 461 } |
464 | 462 |
465 /* gets all cells that originate in a column and have a cellspan > 1 | 463 /* gets all cells that originate in a column and have a cellspan > 1 |
466 Sorts them by increasing cellspan | 464 Sorts them by increasing cellspan |
467 */ | 465 */ |
468 void AutoTableLayout::insertSpanCell(RenderTableCell *cell) | 466 void AutoTableLayout::insertSpanCell(RenderTableCell *cell) |
469 { | 467 { |
470 ASSERT_ARG(cell, cell && cell->colSpan() != 1); | 468 ASSERT_ARG(cell, cell && cell->colSpan() != 1); |
471 if (!cell || cell->colSpan() == 1) | 469 if (!cell || cell->colSpan() == 1) |
472 return; | 470 return; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 default: | 542 default: |
545 break; | 543 break; |
546 } | 544 } |
547 } | 545 } |
548 | 546 |
549 // allocate width to percent cols | 547 // allocate width to percent cols |
550 if (available > 0 && havePercent) { | 548 if (available > 0 && havePercent) { |
551 for (size_t i = 0; i < nEffCols; ++i) { | 549 for (size_t i = 0; i < nEffCols; ++i) { |
552 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; | 550 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; |
553 if (logicalWidth.isPercent()) { | 551 if (logicalWidth.isPercent()) { |
554 int cellLogicalWidth = max<int>(m_layoutStruct[i].effectiveMinLo
gicalWidth, minimumValueForLength(logicalWidth, tableLogicalWidth)); | 552 int cellLogicalWidth = std::max<int>(m_layoutStruct[i].effective
MinLogicalWidth, minimumValueForLength(logicalWidth, tableLogicalWidth)); |
555 available += m_layoutStruct[i].computedLogicalWidth - cellLogica
lWidth; | 553 available += m_layoutStruct[i].computedLogicalWidth - cellLogica
lWidth; |
556 m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth; | 554 m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth; |
557 } | 555 } |
558 } | 556 } |
559 if (totalPercent > 100) { | 557 if (totalPercent > 100) { |
560 // remove overallocated space from the last columns | 558 // remove overallocated space from the last columns |
561 int excess = tableLogicalWidth * (totalPercent - 100) / 100; | 559 int excess = tableLogicalWidth * (totalPercent - 100) / 100; |
562 for (unsigned i = nEffCols; i; ) { | 560 for (unsigned i = nEffCols; i; ) { |
563 --i; | 561 --i; |
564 if (m_layoutStruct[i].effectiveLogicalWidth.isPercent()) { | 562 if (m_layoutStruct[i].effectiveLogicalWidth.isPercent()) { |
565 int cellLogicalWidth = m_layoutStruct[i].computedLogicalWidt
h; | 563 int cellLogicalWidth = m_layoutStruct[i].computedLogicalWidt
h; |
566 int reduction = min(cellLogicalWidth, excess); | 564 int reduction = std::min(cellLogicalWidth, excess); |
567 // the lines below might look inconsistent, but that's the w
ay it's handled in mozilla | 565 // the lines below might look inconsistent, but that's the w
ay it's handled in mozilla |
568 excess -= reduction; | 566 excess -= reduction; |
569 int newLogicalWidth = max<int>(m_layoutStruct[i].effectiveMi
nLogicalWidth, cellLogicalWidth - reduction); | 567 int newLogicalWidth = std::max<int>(m_layoutStruct[i].effect
iveMinLogicalWidth, cellLogicalWidth - reduction); |
570 available += cellLogicalWidth - newLogicalWidth; | 568 available += cellLogicalWidth - newLogicalWidth; |
571 m_layoutStruct[i].computedLogicalWidth = newLogicalWidth; | 569 m_layoutStruct[i].computedLogicalWidth = newLogicalWidth; |
572 } | 570 } |
573 } | 571 } |
574 } | 572 } |
575 } | 573 } |
576 | 574 |
577 // then allocate width to fixed cols | 575 // then allocate width to fixed cols |
578 if (available > 0) { | 576 if (available > 0) { |
579 for (size_t i = 0; i < nEffCols; ++i) { | 577 for (size_t i = 0; i < nEffCols; ++i) { |
580 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; | 578 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; |
581 if (logicalWidth.isFixed() && logicalWidth.value() > m_layoutStruct[
i].computedLogicalWidth) { | 579 if (logicalWidth.isFixed() && logicalWidth.value() > m_layoutStruct[
i].computedLogicalWidth) { |
582 available += m_layoutStruct[i].computedLogicalWidth - logicalWid
th.value(); | 580 available += m_layoutStruct[i].computedLogicalWidth - logicalWid
th.value(); |
583 m_layoutStruct[i].computedLogicalWidth = logicalWidth.value(); | 581 m_layoutStruct[i].computedLogicalWidth = logicalWidth.value(); |
584 } | 582 } |
585 } | 583 } |
586 } | 584 } |
587 | 585 |
588 // now satisfy variable | 586 // now satisfy variable |
589 if (available > 0 && numAuto) { | 587 if (available > 0 && numAuto) { |
590 available += allocAuto; // this gets redistributed | 588 available += allocAuto; // this gets redistributed |
591 for (size_t i = 0; i < nEffCols; ++i) { | 589 for (size_t i = 0; i < nEffCols; ++i) { |
592 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; | 590 Length& logicalWidth = m_layoutStruct[i].effectiveLogicalWidth; |
593 if (logicalWidth.isAuto() && totalAuto && !m_layoutStruct[i].emptyCe
llsOnly) { | 591 if (logicalWidth.isAuto() && totalAuto && !m_layoutStruct[i].emptyCe
llsOnly) { |
594 int cellLogicalWidth = max<int>(m_layoutStruct[i].computedLogica
lWidth, static_cast<int>(available * static_cast<float>(m_layoutStruct[i].effect
iveMaxLogicalWidth) / totalAuto)); | 592 int cellLogicalWidth = std::max<int>(m_layoutStruct[i].computedL
ogicalWidth, static_cast<int>(available * static_cast<float>(m_layoutStruct[i].e
ffectiveMaxLogicalWidth) / totalAuto)); |
595 available -= cellLogicalWidth; | 593 available -= cellLogicalWidth; |
596 totalAuto -= m_layoutStruct[i].effectiveMaxLogicalWidth; | 594 totalAuto -= m_layoutStruct[i].effectiveMaxLogicalWidth; |
597 m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth; | 595 m_layoutStruct[i].computedLogicalWidth = cellLogicalWidth; |
598 } | 596 } |
599 } | 597 } |
600 } | 598 } |
601 | 599 |
602 // spread over fixed columns | 600 // spread over fixed columns |
603 if (available > 0 && numFixed) { | 601 if (available > 0 && numFixed) { |
604 for (size_t i = 0; i < nEffCols; ++i) { | 602 for (size_t i = 0; i < nEffCols; ++i) { |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 | 724 |
727 int pos = 0; | 725 int pos = 0; |
728 for (size_t i = 0; i < nEffCols; ++i) { | 726 for (size_t i = 0; i < nEffCols; ++i) { |
729 m_table->setColumnPosition(i, pos); | 727 m_table->setColumnPosition(i, pos); |
730 pos += m_layoutStruct[i].computedLogicalWidth + m_table->hBorderSpacing(
); | 728 pos += m_layoutStruct[i].computedLogicalWidth + m_table->hBorderSpacing(
); |
731 } | 729 } |
732 m_table->setColumnPosition(m_table->columnPositions().size() - 1, pos); | 730 m_table->setColumnPosition(m_table->columnPositions().size() - 1, pos); |
733 } | 731 } |
734 | 732 |
735 } | 733 } |
OLD | NEW |