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 15 matching lines...) Expand all Loading... |
26 #include "core/layout/LayoutTableCol.h" | 26 #include "core/layout/LayoutTableCol.h" |
27 #include "core/layout/LayoutTableSection.h" | 27 #include "core/layout/LayoutTableSection.h" |
28 #include "core/layout/TextAutosizer.h" | 28 #include "core/layout/TextAutosizer.h" |
29 | 29 |
30 namespace blink { | 30 namespace blink { |
31 | 31 |
32 TableLayoutAlgorithmAuto::TableLayoutAlgorithmAuto(LayoutTable* table) | 32 TableLayoutAlgorithmAuto::TableLayoutAlgorithmAuto(LayoutTable* table) |
33 : TableLayoutAlgorithm(table) | 33 : TableLayoutAlgorithm(table) |
34 , m_hasPercent(false) | 34 , m_hasPercent(false) |
35 , m_effectiveLogicalWidthDirty(true) | 35 , m_effectiveLogicalWidthDirty(true) |
| 36 , m_scaledWidthFromPercentColumns() |
36 { | 37 { |
37 } | 38 } |
38 | 39 |
39 TableLayoutAlgorithmAuto::~TableLayoutAlgorithmAuto() | 40 TableLayoutAlgorithmAuto::~TableLayoutAlgorithmAuto() |
40 { | 41 { |
41 } | 42 } |
42 | 43 |
43 void TableLayoutAlgorithmAuto::recalcColumn(unsigned effCol) | 44 void TableLayoutAlgorithmAuto::recalcColumn(unsigned effCol) |
44 { | 45 { |
45 Layout& columnLayout = m_layoutStruct[effCol]; | 46 Layout& columnLayout = m_layoutStruct[effCol]; |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 | 171 |
171 // For the last column in a column-group, we invalidate our group logica
l width. | 172 // For the last column in a column-group, we invalidate our group logica
l width. |
172 if (column->isTableColumn() && !column->nextSibling()) | 173 if (column->isTableColumn() && !column->nextSibling()) |
173 groupLogicalWidth = Length(); | 174 groupLogicalWidth = Length(); |
174 } | 175 } |
175 | 176 |
176 for (unsigned i = 0; i < nEffCols; i++) | 177 for (unsigned i = 0; i < nEffCols; i++) |
177 recalcColumn(i); | 178 recalcColumn(i); |
178 } | 179 } |
179 | 180 |
| 181 static bool shouldScaleColumnsForParent(LayoutTable* table) |
| 182 { |
| 183 LayoutBlock* cb = table->containingBlock(); |
| 184 while (!cb->isLayoutView()) { |
| 185 // It doesn't matter if our table is auto or fixed: auto means we don't |
| 186 // scale. Fixed doesn't care if we do or not because it doesn't depend |
| 187 // on the cell contents' preferred widths. |
| 188 if (cb->isTableCell()) |
| 189 return false; |
| 190 cb = cb->containingBlock(); |
| 191 } |
| 192 return true; |
| 193 } |
| 194 |
180 // FIXME: This needs to be adapted for vertical writing modes. | 195 // FIXME: This needs to be adapted for vertical writing modes. |
181 static bool shouldScaleColumns(LayoutTable* table) | 196 static bool shouldScaleColumnsForSelf(LayoutTable* table) |
182 { | 197 { |
| 198 // Normally, scale all columns to satisfy this from CSS2.2: |
| 199 // "A percentage value for a column width is relative to the table width. |
| 200 // If the table has 'width: auto', a percentage represents a constraint on t
he column's width" |
| 201 |
183 // A special case. If this table is not fixed width and contained inside | 202 // A special case. If this table is not fixed width and contained inside |
184 // a cell, then don't bloat the maxwidth by examining percentage growth. | 203 // a cell, then don't bloat the maxwidth by examining percentage growth. |
185 while (true) { | 204 while (true) { |
186 Length tw = table->style()->width(); | 205 Length tw = table->style()->width(); |
187 if ((!tw.isAuto() && !tw.hasPercent()) || table->isOutOfFlowPositioned()
) | 206 if ((!tw.isAuto() && !tw.hasPercent()) || table->isOutOfFlowPositioned()
) |
188 return true; | 207 return true; |
189 LayoutBlock* cb = table->containingBlock(); | 208 LayoutBlock* cb = table->containingBlock(); |
190 | 209 |
191 while (!cb->isLayoutView() && !cb->isTableCell() | 210 while (!cb->isLayoutView() && !cb->isTableCell() |
192 && cb->style()->width().isAuto() && !cb->isOutOfFlowPositioned()) | 211 && cb->style()->width().isAuto() && !cb->isOutOfFlowPositioned()) |
(...skipping 17 matching lines...) Expand all Loading... |
210 { | 229 { |
211 TextAutosizer::TableLayoutScope textAutosizerTableLayoutScope(m_table); | 230 TextAutosizer::TableLayoutScope textAutosizerTableLayoutScope(m_table); |
212 | 231 |
213 fullRecalc(); | 232 fullRecalc(); |
214 | 233 |
215 int spanMaxLogicalWidth = calcEffectiveLogicalWidth(); | 234 int spanMaxLogicalWidth = calcEffectiveLogicalWidth(); |
216 minWidth = LayoutUnit(); | 235 minWidth = LayoutUnit(); |
217 maxWidth = LayoutUnit(); | 236 maxWidth = LayoutUnit(); |
218 float maxPercent = 0; | 237 float maxPercent = 0; |
219 float maxNonPercent = 0; | 238 float maxNonPercent = 0; |
220 bool scaleColumns = shouldScaleColumns(m_table); | 239 bool scaleColumnsForSelf = shouldScaleColumnsForSelf(m_table); |
221 | 240 |
222 // We substitute 0 percent by (epsilon / percentScaleFactor) percent in two
places below to avoid division by zero. | 241 // We substitute 0 percent by (epsilon / percentScaleFactor) percent in two
places below to avoid division by zero. |
223 // FIXME: Handle the 0% cases properly. | 242 // FIXME: Handle the 0% cases properly. |
224 const float epsilon = 1 / 128.0f; | 243 const float epsilon = 1 / 128.0f; |
225 | 244 |
226 float remainingPercent = 100; | 245 float remainingPercent = 100; |
227 for (size_t i = 0; i < m_layoutStruct.size(); ++i) { | 246 for (size_t i = 0; i < m_layoutStruct.size(); ++i) { |
228 minWidth += m_layoutStruct[i].effectiveMinLogicalWidth; | 247 minWidth += m_layoutStruct[i].effectiveMinLogicalWidth; |
229 maxWidth += m_layoutStruct[i].effectiveMaxLogicalWidth; | 248 maxWidth += m_layoutStruct[i].effectiveMaxLogicalWidth; |
230 if (scaleColumns) { | 249 if (scaleColumnsForSelf) { |
231 if (m_layoutStruct[i].effectiveLogicalWidth.hasPercent()) { | 250 if (m_layoutStruct[i].effectiveLogicalWidth.hasPercent()) { |
232 float percent = std::min(static_cast<float>(m_layoutStruct[i].ef
fectiveLogicalWidth.percent()), remainingPercent); | 251 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 / std::max(percent, epsilon); | 252 float logicalWidth = static_cast<float>(m_layoutStruct[i].effect
iveMaxLogicalWidth) * 100 / std::max(percent, epsilon); |
234 maxPercent = std::max(logicalWidth, maxPercent); | 253 maxPercent = std::max(logicalWidth, maxPercent); |
235 remainingPercent -= percent; | 254 remainingPercent -= percent; |
236 } else { | 255 } else { |
237 maxNonPercent += m_layoutStruct[i].effectiveMaxLogicalWidth; | 256 maxNonPercent += m_layoutStruct[i].effectiveMaxLogicalWidth; |
238 } | 257 } |
239 } | 258 } |
240 } | 259 } |
241 | 260 |
242 if (scaleColumns) { | 261 if (scaleColumnsForSelf) { |
243 maxNonPercent = maxNonPercent * 100 / std::max(remainingPercent, epsilon
); | 262 maxNonPercent = maxNonPercent * 100 / std::max(remainingPercent, epsilon
); |
244 maxWidth = std::max(maxWidth, LayoutUnit(std::min(maxNonPercent, static_
cast<float>(tableMaxWidth)))); | 263 m_scaledWidthFromPercentColumns = LayoutUnit(std::min(maxNonPercent, sta
tic_cast<float>(tableMaxWidth))); |
245 maxWidth = std::max(maxWidth, LayoutUnit(std::min(maxPercent, static_cas
t<float>(tableMaxWidth)))); | 264 m_scaledWidthFromPercentColumns = std::max(m_scaledWidthFromPercentColum
ns, LayoutUnit(std::min(maxPercent, static_cast<float>(tableMaxWidth)))); |
| 265 if (m_scaledWidthFromPercentColumns > maxWidth && shouldScaleColumnsForP
arent(m_table)) |
| 266 maxWidth = m_scaledWidthFromPercentColumns; |
246 } | 267 } |
247 | 268 |
248 maxWidth = LayoutUnit(std::max(maxWidth.floor(), spanMaxLogicalWidth)); | 269 maxWidth = LayoutUnit(std::max(maxWidth.floor(), spanMaxLogicalWidth)); |
249 } | 270 } |
250 | 271 |
251 void TableLayoutAlgorithmAuto::applyPreferredLogicalWidthQuirks(LayoutUnit& minW
idth, LayoutUnit& maxWidth) const | 272 void TableLayoutAlgorithmAuto::applyPreferredLogicalWidthQuirks(LayoutUnit& minW
idth, LayoutUnit& maxWidth) const |
252 { | 273 { |
253 Length tableLogicalWidth = m_table->style()->logicalWidth(); | 274 Length tableLogicalWidth = m_table->style()->logicalWidth(); |
254 if (tableLogicalWidth.isFixed() && tableLogicalWidth.isPositive()) { | 275 if (tableLogicalWidth.isFixed() && tableLogicalWidth.isPositive()) { |
255 // |minWidth| is the result of measuring the intrinsic content's size. K
eep it to | 276 // |minWidth| is the result of measuring the intrinsic content's size. K
eep it to |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 int reduce = available * minMaxDiff / logicalWidthBeyondMin; | 715 int reduce = available * minMaxDiff / logicalWidthBeyondMin; |
695 m_layoutStruct[i].computedLogicalWidth += reduce; | 716 m_layoutStruct[i].computedLogicalWidth += reduce; |
696 available -= reduce; | 717 available -= reduce; |
697 logicalWidthBeyondMin -= minMaxDiff; | 718 logicalWidthBeyondMin -= minMaxDiff; |
698 if (available >= 0) | 719 if (available >= 0) |
699 break; | 720 break; |
700 } | 721 } |
701 } | 722 } |
702 } | 723 } |
703 } // namespace blink | 724 } // namespace blink |
OLD | NEW |