Chromium Code Reviews| 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(0) | |
|
mstensho (USE GERRIT)
2016/05/18 19:50:17
No need to explicitly initialize LayoutUnit to 0.
dgrogan
2016/05/18 22:28:33
Done.
| |
| 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; |
| 246 | |
| 227 for (size_t i = 0; i < m_layoutStruct.size(); ++i) { | 247 for (size_t i = 0; i < m_layoutStruct.size(); ++i) { |
| 228 minWidth += m_layoutStruct[i].effectiveMinLogicalWidth; | 248 minWidth += m_layoutStruct[i].effectiveMinLogicalWidth; |
| 229 maxWidth += m_layoutStruct[i].effectiveMaxLogicalWidth; | 249 maxWidth += m_layoutStruct[i].effectiveMaxLogicalWidth; |
| 230 if (scaleColumns) { | 250 if (scaleColumnsForSelf) { |
| 231 if (m_layoutStruct[i].effectiveLogicalWidth.hasPercent()) { | 251 if (m_layoutStruct[i].effectiveLogicalWidth.hasPercent()) { |
| 232 float percent = std::min(static_cast<float>(m_layoutStruct[i].ef fectiveLogicalWidth.percent()), remainingPercent); | 252 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); | 253 float logicalWidth = static_cast<float>(m_layoutStruct[i].effect iveMaxLogicalWidth) * 100 / std::max(percent, epsilon); |
| 234 maxPercent = std::max(logicalWidth, maxPercent); | 254 maxPercent = std::max(logicalWidth, maxPercent); |
| 235 remainingPercent -= percent; | 255 remainingPercent -= percent; |
| 236 } else { | 256 } else { |
| 237 maxNonPercent += m_layoutStruct[i].effectiveMaxLogicalWidth; | 257 maxNonPercent += m_layoutStruct[i].effectiveMaxLogicalWidth; |
| 238 } | 258 } |
| 239 } | 259 } |
| 240 } | 260 } |
| 241 | 261 if (scaleColumnsForSelf) { |
| 242 if (scaleColumns) { | |
| 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)))); |
| 246 } | 265 } |
| 247 | 266 |
| 267 if (shouldScaleColumnsForParent(m_table)) { | |
|
mstensho (USE GERRIT)
2016/05/18 19:50:17
Should probably check |scaleColumnsForSelf| first,
dgrogan
2016/05/18 22:28:33
Done. Well, I changed to checking to see if m_scal
| |
| 268 DCHECK(scaleColumnsForSelf); | |
| 269 maxWidth = std::max(m_scaledWidthFromPercentColumns, maxWidth); | |
| 270 } | |
| 248 maxWidth = LayoutUnit(std::max(maxWidth.floor(), spanMaxLogicalWidth)); | 271 maxWidth = LayoutUnit(std::max(maxWidth.floor(), spanMaxLogicalWidth)); |
| 249 } | 272 } |
| 250 | 273 |
| 274 LayoutUnit TableLayoutAlgorithmAuto::scaledWidthFromPercentColumns() | |
|
mstensho (USE GERRIT)
2016/05/18 19:50:17
Make this inline?
dgrogan
2016/05/18 22:28:33
Done.
| |
| 275 { | |
| 276 return m_scaledWidthFromPercentColumns; | |
| 277 } | |
| 278 | |
| 251 void TableLayoutAlgorithmAuto::applyPreferredLogicalWidthQuirks(LayoutUnit& minW idth, LayoutUnit& maxWidth) const | 279 void TableLayoutAlgorithmAuto::applyPreferredLogicalWidthQuirks(LayoutUnit& minW idth, LayoutUnit& maxWidth) const |
| 252 { | 280 { |
| 253 Length tableLogicalWidth = m_table->style()->logicalWidth(); | 281 Length tableLogicalWidth = m_table->style()->logicalWidth(); |
| 254 if (tableLogicalWidth.isFixed() && tableLogicalWidth.isPositive()) { | 282 if (tableLogicalWidth.isFixed() && tableLogicalWidth.isPositive()) { |
| 255 // |minWidth| is the result of measuring the intrinsic content's size. K eep it to | 283 // |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. | 284 // make sure we are *never* smaller than the actual content. |
| 257 LayoutUnit minContentWidth = minWidth; | 285 LayoutUnit minContentWidth = minWidth; |
| 258 // FIXME: This line looks REALLY suspicious as it could allow the minimu m | 286 // FIXME: This line looks REALLY suspicious as it could allow the minimu m |
| 259 // preferred logical width to be smaller than the table content. This ha s | 287 // preferred logical width to be smaller than the table content. This ha s |
| 260 // to be cross-checked against other browsers. | 288 // to be cross-checked against other browsers. |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 694 int reduce = available * minMaxDiff / logicalWidthBeyondMin; | 722 int reduce = available * minMaxDiff / logicalWidthBeyondMin; |
| 695 m_layoutStruct[i].computedLogicalWidth += reduce; | 723 m_layoutStruct[i].computedLogicalWidth += reduce; |
| 696 available -= reduce; | 724 available -= reduce; |
| 697 logicalWidthBeyondMin -= minMaxDiff; | 725 logicalWidthBeyondMin -= minMaxDiff; |
| 698 if (available >= 0) | 726 if (available >= 0) |
| 699 break; | 727 break; |
| 700 } | 728 } |
| 701 } | 729 } |
| 702 } | 730 } |
| 703 } // namespace blink | 731 } // namespace blink |
| OLD | NEW |