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 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 |