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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
170 | 170 |
171 // For the last column in a column-group, we invalidate our group logica l width. | 171 // For the last column in a column-group, we invalidate our group logica l width. |
172 if (column->isTableColumn() && !column->nextSibling()) | 172 if (column->isTableColumn() && !column->nextSibling()) |
173 groupLogicalWidth = Length(); | 173 groupLogicalWidth = Length(); |
174 } | 174 } |
175 | 175 |
176 for (unsigned i = 0; i < nEffCols; i++) | 176 for (unsigned i = 0; i < nEffCols; i++) |
177 recalcColumn(i); | 177 recalcColumn(i); |
178 } | 178 } |
179 | 179 |
180 static bool shouldScaleColumnsForParent(LayoutTable* table) | |
181 { | |
182 return !table->containingBlock()->isTableCell(); | |
dgrogan
2016/04/28 01:04:31
This is the naive first cut. It doesn't even imple
mstensho (USE GERRIT)
2016/04/28 09:18:05
I see. This approach should in theory not cause an
| |
183 } | |
184 | |
180 // FIXME: This needs to be adapted for vertical writing modes. | 185 // FIXME: This needs to be adapted for vertical writing modes. |
181 static bool shouldScaleColumns(LayoutTable* table) | 186 static bool shouldScaleColumnsForSelf(LayoutTable* table) |
182 { | 187 { |
183 // A special case. If this table is not fixed width and contained inside | 188 // 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. | 189 // a cell, then don't bloat the maxwidth by examining percentage growth. |
185 while (true) { | 190 while (true) { |
186 Length tw = table->style()->width(); | 191 Length tw = table->style()->width(); |
187 if ((!tw.isAuto() && !tw.hasPercent()) || table->isOutOfFlowPositioned() ) | 192 if ((!tw.isAuto() && !tw.hasPercent()) || table->isOutOfFlowPositioned() ) |
188 return true; | 193 return true; |
189 LayoutBlock* cb = table->containingBlock(); | 194 LayoutBlock* cb = table->containingBlock(); |
190 | 195 |
191 while (!cb->isLayoutView() && !cb->isTableCell() | 196 while (!cb->isLayoutView() && !cb->isTableCell() |
(...skipping 16 matching lines...) Expand all Loading... | |
208 | 213 |
209 void TableLayoutAlgorithmAuto::computeIntrinsicLogicalWidths(LayoutUnit& minWidt h, LayoutUnit& maxWidth) | 214 void TableLayoutAlgorithmAuto::computeIntrinsicLogicalWidths(LayoutUnit& minWidt h, LayoutUnit& maxWidth) |
210 { | 215 { |
211 TextAutosizer::TableLayoutScope textAutosizerTableLayoutScope(m_table); | 216 TextAutosizer::TableLayoutScope textAutosizerTableLayoutScope(m_table); |
212 | 217 |
213 fullRecalc(); | 218 fullRecalc(); |
214 | 219 |
215 int spanMaxLogicalWidth = calcEffectiveLogicalWidth(); | 220 int spanMaxLogicalWidth = calcEffectiveLogicalWidth(); |
216 minWidth = LayoutUnit(); | 221 minWidth = LayoutUnit(); |
217 maxWidth = LayoutUnit(); | 222 maxWidth = LayoutUnit(); |
223 | |
224 for (size_t i = 0; i < m_layoutStruct.size(); ++i) { | |
225 minWidth += m_layoutStruct[i].effectiveMinLogicalWidth; | |
226 maxWidth += m_layoutStruct[i].effectiveMaxLogicalWidth; | |
227 } | |
228 if (shouldScaleColumnsForParent(m_table)) | |
229 maxWidth = std::max(maxWidth, scaledWidthFromPercentColumns()); | |
230 maxWidth = LayoutUnit(std::max(maxWidth.floor(), spanMaxLogicalWidth)); | |
231 } | |
232 | |
233 LayoutUnit TableLayoutAlgorithmAuto::scaledWidthFromPercentColumns() | |
dgrogan
2016/04/28 01:04:31
Ignore that this is a separate function for now. I
| |
234 { | |
235 // Normally, scale all columns to satisfy this from CSS2.2: | |
236 // "A percentage value for a column width is relative to the table width. | |
237 // If the table has 'width: auto', a percentage represents a constraint on t he column's width" | |
238 if (!shouldScaleColumnsForSelf(m_table)) | |
239 return LayoutUnit(0); | |
240 | |
218 float maxPercent = 0; | 241 float maxPercent = 0; |
219 float maxNonPercent = 0; | 242 float maxNonPercent = 0; |
220 bool scaleColumns = shouldScaleColumns(m_table); | |
221 | 243 |
222 // We substitute 0 percent by (epsilon / percentScaleFactor) percent in two places below to avoid division by zero. | 244 // We substitute 0 percent by (epsilon / percentScaleFactor) percent in two places below to avoid division by zero. |
223 // FIXME: Handle the 0% cases properly. | 245 // FIXME: Handle the 0% cases properly. |
224 const float epsilon = 1 / 128.0f; | 246 const float epsilon = 1 / 128.0f; |
225 | 247 |
226 float remainingPercent = 100; | 248 float remainingPercent = 100; |
227 for (size_t i = 0; i < m_layoutStruct.size(); ++i) { | 249 for (size_t i = 0; i < m_layoutStruct.size(); ++i) { |
228 minWidth += m_layoutStruct[i].effectiveMinLogicalWidth; | 250 if (m_layoutStruct[i].effectiveLogicalWidth.hasPercent()) { |
229 maxWidth += m_layoutStruct[i].effectiveMaxLogicalWidth; | 251 float percent = std::min(static_cast<float>(m_layoutStruct[i].effect iveLogicalWidth.percent()), remainingPercent); |
230 if (scaleColumns) { | 252 float logicalWidth = static_cast<float>(m_layoutStruct[i].effectiveM axLogicalWidth) * 100 / std::max(percent, epsilon); |
231 if (m_layoutStruct[i].effectiveLogicalWidth.hasPercent()) { | 253 maxPercent = std::max(logicalWidth, maxPercent); |
232 float percent = std::min(static_cast<float>(m_layoutStruct[i].ef fectiveLogicalWidth.percent()), remainingPercent); | 254 remainingPercent -= percent; |
233 float logicalWidth = static_cast<float>(m_layoutStruct[i].effect iveMaxLogicalWidth) * 100 / std::max(percent, epsilon); | 255 } else { |
234 maxPercent = std::max(logicalWidth, maxPercent); | 256 maxNonPercent += m_layoutStruct[i].effectiveMaxLogicalWidth; |
235 remainingPercent -= percent; | |
236 } else { | |
237 maxNonPercent += m_layoutStruct[i].effectiveMaxLogicalWidth; | |
238 } | |
239 } | 257 } |
240 } | 258 } |
241 | 259 |
242 if (scaleColumns) { | 260 maxNonPercent = maxNonPercent * 100 / std::max(remainingPercent, epsilon); |
243 maxNonPercent = maxNonPercent * 100 / std::max(remainingPercent, epsilon ); | 261 LayoutUnit maxWidth = LayoutUnit(std::min(maxNonPercent, static_cast<float>( tableMaxWidth))); |
244 maxWidth = std::max(maxWidth, LayoutUnit(std::min(maxNonPercent, static_ cast<float>(tableMaxWidth)))); | 262 return std::max(maxWidth, LayoutUnit(std::min(maxPercent, static_cast<float> (tableMaxWidth)))); |
245 maxWidth = std::max(maxWidth, LayoutUnit(std::min(maxPercent, static_cas t<float>(tableMaxWidth)))); | |
246 } | |
247 | |
248 maxWidth = LayoutUnit(std::max(maxWidth.floor(), spanMaxLogicalWidth)); | |
249 } | 263 } |
250 | 264 |
251 void TableLayoutAlgorithmAuto::applyPreferredLogicalWidthQuirks(LayoutUnit& minW idth, LayoutUnit& maxWidth) const | 265 void TableLayoutAlgorithmAuto::applyPreferredLogicalWidthQuirks(LayoutUnit& minW idth, LayoutUnit& maxWidth) const |
252 { | 266 { |
253 Length tableLogicalWidth = m_table->style()->logicalWidth(); | 267 Length tableLogicalWidth = m_table->style()->logicalWidth(); |
254 if (tableLogicalWidth.isFixed() && tableLogicalWidth.isPositive()) { | 268 if (tableLogicalWidth.isFixed() && tableLogicalWidth.isPositive()) { |
255 // |minWidth| is the result of measuring the intrinsic content's size. K eep it to | 269 // |minWidth| is the result of measuring the intrinsic content's size. K eep it to |
256 // make sure we are *never* smaller than the actual content. | 270 // make sure we are *never* smaller than the actual content. |
257 LayoutUnit minContentWidth = minWidth; | 271 LayoutUnit minContentWidth = minWidth; |
258 // FIXME: This line looks REALLY suspicious as it could allow the minimu m | 272 // FIXME: This line looks REALLY suspicious as it could allow the minimu m |
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
694 int reduce = available * minMaxDiff / logicalWidthBeyondMin; | 708 int reduce = available * minMaxDiff / logicalWidthBeyondMin; |
695 m_layoutStruct[i].computedLogicalWidth += reduce; | 709 m_layoutStruct[i].computedLogicalWidth += reduce; |
696 available -= reduce; | 710 available -= reduce; |
697 logicalWidthBeyondMin -= minMaxDiff; | 711 logicalWidthBeyondMin -= minMaxDiff; |
698 if (available >= 0) | 712 if (available >= 0) |
699 break; | 713 break; |
700 } | 714 } |
701 } | 715 } |
702 } | 716 } |
703 } // namespace blink | 717 } // namespace blink |
OLD | NEW |