| 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, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. | 4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. |
| 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 uses the 'overflow' property to determine whether to clip the | 67 uses the 'overflow' property to determine whether to clip the |
| 68 overflow content. | 68 overflow content. |
| 69 */ | 69 */ |
| 70 | 70 |
| 71 namespace blink { | 71 namespace blink { |
| 72 | 72 |
| 73 TableLayoutAlgorithmFixed::TableLayoutAlgorithmFixed(LayoutTable* table) | 73 TableLayoutAlgorithmFixed::TableLayoutAlgorithmFixed(LayoutTable* table) |
| 74 : TableLayoutAlgorithm(table) {} | 74 : TableLayoutAlgorithm(table) {} |
| 75 | 75 |
| 76 int TableLayoutAlgorithmFixed::calcWidthArray() { | 76 int TableLayoutAlgorithmFixed::calcWidthArray() { |
| 77 // FIXME: We might want to wait until we have all of the first row before comp
uting for the first time. | 77 // FIXME: We might want to wait until we have all of the first row before |
| 78 // computing for the first time. |
| 78 int usedWidth = 0; | 79 int usedWidth = 0; |
| 79 | 80 |
| 80 // iterate over all <col> elements | 81 // iterate over all <col> elements |
| 81 unsigned nEffCols = m_table->numEffectiveColumns(); | 82 unsigned nEffCols = m_table->numEffectiveColumns(); |
| 82 m_width.resize(nEffCols); | 83 m_width.resize(nEffCols); |
| 83 m_width.fill(Length(Auto)); | 84 m_width.fill(Length(Auto)); |
| 84 | 85 |
| 85 unsigned currentEffectiveColumn = 0; | 86 unsigned currentEffectiveColumn = 0; |
| 86 for (LayoutTableCol* col = m_table->firstColumn(); col; | 87 for (LayoutTableCol* col = m_table->firstColumn(); col; |
| 87 col = col->nextColumn()) { | 88 col = col->nextColumn()) { |
| 88 // LayoutTableCols don't have the concept of preferred logical width, but we
need to clear their dirty bits | 89 // LayoutTableCols don't have the concept of preferred logical width, but we |
| 89 // so that if we call setPreferredWidthsDirty(true) on a col or one of its d
escendants, we'll mark it's | 90 // need to clear their dirty bits so that if we call |
| 90 // ancestors as dirty. | 91 // setPreferredWidthsDirty(true) on a col or one of its descendants, we'll |
| 92 // mark it's ancestors as dirty. |
| 91 col->clearPreferredLogicalWidthsDirtyBits(); | 93 col->clearPreferredLogicalWidthsDirtyBits(); |
| 92 | 94 |
| 93 // Width specified by column-groups that have column child does not affect c
olumn width in fixed layout tables | 95 // Width specified by column-groups that have column child does not affect |
| 96 // column width in fixed layout tables |
| 94 if (col->isTableColumnGroupWithColumnChildren()) | 97 if (col->isTableColumnGroupWithColumnChildren()) |
| 95 continue; | 98 continue; |
| 96 | 99 |
| 97 Length colStyleLogicalWidth = col->style()->logicalWidth(); | 100 Length colStyleLogicalWidth = col->style()->logicalWidth(); |
| 98 int effectiveColWidth = 0; | 101 int effectiveColWidth = 0; |
| 99 if (colStyleLogicalWidth.isFixed() && colStyleLogicalWidth.value() > 0) | 102 if (colStyleLogicalWidth.isFixed() && colStyleLogicalWidth.value() > 0) |
| 100 effectiveColWidth = colStyleLogicalWidth.value(); | 103 effectiveColWidth = colStyleLogicalWidth.value(); |
| 101 | 104 |
| 102 unsigned span = col->span(); | 105 unsigned span = col->span(); |
| 103 while (span) { | 106 while (span) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 134 if (!section) | 137 if (!section) |
| 135 return usedWidth; | 138 return usedWidth; |
| 136 | 139 |
| 137 unsigned currentColumn = 0; | 140 unsigned currentColumn = 0; |
| 138 | 141 |
| 139 LayoutTableRow* firstRow = section->firstRow(); | 142 LayoutTableRow* firstRow = section->firstRow(); |
| 140 for (LayoutTableCell* cell = firstRow->firstCell(); cell; | 143 for (LayoutTableCell* cell = firstRow->firstCell(); cell; |
| 141 cell = cell->nextCell()) { | 144 cell = cell->nextCell()) { |
| 142 Length logicalWidth = cell->styleOrColLogicalWidth(); | 145 Length logicalWidth = cell->styleOrColLogicalWidth(); |
| 143 | 146 |
| 144 // FIXME: calc() on tables should be handled consistently with other lengths
. See bug: https://crbug.com/382725 | 147 // FIXME: calc() on tables should be handled consistently with other |
| 148 // lengths. See bug: https://crbug.com/382725 |
| 145 if (logicalWidth.isCalculated()) | 149 if (logicalWidth.isCalculated()) |
| 146 logicalWidth = Length(); // Make it Auto | 150 logicalWidth = Length(); // Make it Auto |
| 147 | 151 |
| 148 unsigned span = cell->colSpan(); | 152 unsigned span = cell->colSpan(); |
| 149 int fixedBorderBoxLogicalWidth = 0; | 153 int fixedBorderBoxLogicalWidth = 0; |
| 150 // FIXME: Support other length types. If the width is non-auto, it should pr
obably just use | 154 // FIXME: Support other length types. If the width is non-auto, it should |
| 151 // LayoutBox::computeLogicalWidthUsing to compute the width. | 155 // probably just use LayoutBox::computeLogicalWidthUsing to compute the |
| 156 // width. |
| 152 if (logicalWidth.isFixed() && logicalWidth.isPositive()) { | 157 if (logicalWidth.isFixed() && logicalWidth.isPositive()) { |
| 153 fixedBorderBoxLogicalWidth = | 158 fixedBorderBoxLogicalWidth = |
| 154 cell->adjustBorderBoxLogicalWidthForBoxSizing(logicalWidth.value()) | 159 cell->adjustBorderBoxLogicalWidthForBoxSizing(logicalWidth.value()) |
| 155 .toInt(); | 160 .toInt(); |
| 156 logicalWidth.setValue(fixedBorderBoxLogicalWidth); | 161 logicalWidth.setValue(fixedBorderBoxLogicalWidth); |
| 157 } | 162 } |
| 158 | 163 |
| 159 unsigned usedSpan = 0; | 164 unsigned usedSpan = 0; |
| 160 while (usedSpan < span && currentColumn < nEffCols) { | 165 while (usedSpan < span && currentColumn < nEffCols) { |
| 161 float eSpan = m_table->spanOfEffectiveColumn(currentColumn); | 166 float eSpan = m_table->spanOfEffectiveColumn(currentColumn); |
| 162 // Only set if no col element has already set it. | 167 // Only set if no col element has already set it. |
| 163 if (m_width[currentColumn].isAuto() && logicalWidth.type() != Auto) { | 168 if (m_width[currentColumn].isAuto() && logicalWidth.type() != Auto) { |
| 164 m_width[currentColumn] = logicalWidth; | 169 m_width[currentColumn] = logicalWidth; |
| 165 m_width[currentColumn] *= eSpan / span; | 170 m_width[currentColumn] *= eSpan / span; |
| 166 usedWidth += fixedBorderBoxLogicalWidth * eSpan / span; | 171 usedWidth += fixedBorderBoxLogicalWidth * eSpan / span; |
| 167 } | 172 } |
| 168 usedSpan += eSpan; | 173 usedSpan += eSpan; |
| 169 ++currentColumn; | 174 ++currentColumn; |
| 170 } | 175 } |
| 171 | 176 |
| 172 // TableLayoutAlgorithmFixed doesn't use min/maxPreferredLogicalWidths, but
we need to clear the | 177 // TableLayoutAlgorithmFixed doesn't use min/maxPreferredLogicalWidths, but |
| 173 // dirty bit on the cell so that we'll correctly mark its ancestors dirty | 178 // we need to clear the dirty bit on the cell so that we'll correctly mark |
| 174 // in case we later call setPreferredLogicalWidthsDirty() on it later. | 179 // its ancestors dirty in case we later call |
| 180 // setPreferredLogicalWidthsDirty() on it later. |
| 175 if (cell->preferredLogicalWidthsDirty()) | 181 if (cell->preferredLogicalWidthsDirty()) |
| 176 cell->clearPreferredLogicalWidthsDirty(); | 182 cell->clearPreferredLogicalWidthsDirty(); |
| 177 } | 183 } |
| 178 | 184 |
| 179 return usedWidth; | 185 return usedWidth; |
| 180 } | 186 } |
| 181 | 187 |
| 182 void TableLayoutAlgorithmFixed::computeIntrinsicLogicalWidths( | 188 void TableLayoutAlgorithmFixed::computeIntrinsicLogicalWidths( |
| 183 LayoutUnit& minWidth, | 189 LayoutUnit& minWidth, |
| 184 LayoutUnit& maxWidth) { | 190 LayoutUnit& maxWidth) { |
| 185 minWidth = maxWidth = LayoutUnit(calcWidthArray()); | 191 minWidth = maxWidth = LayoutUnit(calcWidthArray()); |
| 186 } | 192 } |
| 187 | 193 |
| 188 void TableLayoutAlgorithmFixed::applyPreferredLogicalWidthQuirks( | 194 void TableLayoutAlgorithmFixed::applyPreferredLogicalWidthQuirks( |
| 189 LayoutUnit& minWidth, | 195 LayoutUnit& minWidth, |
| 190 LayoutUnit& maxWidth) const { | 196 LayoutUnit& maxWidth) const { |
| 191 Length tableLogicalWidth = m_table->style()->logicalWidth(); | 197 Length tableLogicalWidth = m_table->style()->logicalWidth(); |
| 192 if (tableLogicalWidth.isFixed() && tableLogicalWidth.isPositive()) { | 198 if (tableLogicalWidth.isFixed() && tableLogicalWidth.isPositive()) { |
| 193 minWidth = maxWidth = LayoutUnit( | 199 minWidth = maxWidth = LayoutUnit( |
| 194 max(minWidth, | 200 max(minWidth, |
| 195 LayoutUnit(tableLogicalWidth.value() - | 201 LayoutUnit(tableLogicalWidth.value() - |
| 196 m_table->bordersPaddingAndSpacingInRowDirection())) | 202 m_table->bordersPaddingAndSpacingInRowDirection())) |
| 197 .floor()); | 203 .floor()); |
| 198 } | 204 } |
| 199 | 205 |
| 200 /* | 206 /* |
| 201 <table style="width:100%; background-color:red"><tr><td> | 207 <table style="width:100%; background-color:red"><tr><td> |
| 202 <table style="background-color:blue"><tr><td> | 208 <table style="background-color:blue"><tr><td> |
| 203 <table style="width:100%; background-color:green; table-layout:f
ixed"><tr><td> | 209 <table style="width:100%; background-color:green; |
| 210 table-layout:fixed"><tr><td> |
| 204 Content | 211 Content |
| 205 </td></tr></table> | 212 </td></tr></table> |
| 206 </td></tr></table> | 213 </td></tr></table> |
| 207 </td></tr></table> | 214 </td></tr></table> |
| 208 */ | 215 */ |
| 209 // In this example, the two inner tables should be as large as the outer table
. | 216 // In this example, the two inner tables should be as large as the outer |
| 210 // We can achieve this effect by making the maxwidth of fixed tables with perc
entage | 217 // table. We can achieve this effect by making the maxwidth of fixed tables |
| 211 // widths be infinite. | 218 // with percentage widths be infinite. |
| 212 if (m_table->style()->logicalWidth().isPercentOrCalc() && | 219 if (m_table->style()->logicalWidth().isPercentOrCalc() && |
| 213 maxWidth < tableMaxWidth) | 220 maxWidth < tableMaxWidth) |
| 214 maxWidth = LayoutUnit(tableMaxWidth); | 221 maxWidth = LayoutUnit(tableMaxWidth); |
| 215 } | 222 } |
| 216 | 223 |
| 217 void TableLayoutAlgorithmFixed::layout() { | 224 void TableLayoutAlgorithmFixed::layout() { |
| 218 int tableLogicalWidth = (m_table->logicalWidth() - | 225 int tableLogicalWidth = (m_table->logicalWidth() - |
| 219 m_table->bordersPaddingAndSpacingInRowDirection()) | 226 m_table->bordersPaddingAndSpacingInRowDirection()) |
| 220 .toInt(); | 227 .toInt(); |
| 221 unsigned nEffCols = m_table->numEffectiveColumns(); | 228 unsigned nEffCols = m_table->numEffectiveColumns(); |
| 222 | 229 |
| 223 // FIXME: It is possible to be called without having properly updated our inte
rnal representation. | 230 // FIXME: It is possible to be called without having properly updated our |
| 224 // This means that our preferred logical widths were not recomputed as expecte
d. | 231 // internal representation. This means that our preferred logical widths were |
| 232 // not recomputed as expected. |
| 225 if (nEffCols != m_width.size()) { | 233 if (nEffCols != m_width.size()) { |
| 226 calcWidthArray(); | 234 calcWidthArray(); |
| 227 // FIXME: Table layout shouldn't modify our table structure (but does due to
columns and column-groups). | 235 // FIXME: Table layout shouldn't modify our table structure (but does due to |
| 236 // columns and column-groups). |
| 228 nEffCols = m_table->numEffectiveColumns(); | 237 nEffCols = m_table->numEffectiveColumns(); |
| 229 } | 238 } |
| 230 | 239 |
| 231 Vector<int> calcWidth(nEffCols, 0); | 240 Vector<int> calcWidth(nEffCols, 0); |
| 232 | 241 |
| 233 unsigned numAuto = 0; | 242 unsigned numAuto = 0; |
| 234 unsigned autoSpan = 0; | 243 unsigned autoSpan = 0; |
| 235 int totalFixedWidth = 0; | 244 int totalFixedWidth = 0; |
| 236 int totalPercentWidth = 0; | 245 int totalPercentWidth = 0; |
| 237 float totalPercent = 0; | 246 float totalPercent = 0; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 void TableLayoutAlgorithmFixed::willChangeTableLayout() { | 346 void TableLayoutAlgorithmFixed::willChangeTableLayout() { |
| 338 // When switching table layout algorithm, we need to dirty the preferred | 347 // When switching table layout algorithm, we need to dirty the preferred |
| 339 // logical widths as we cleared the bits without computing them. | 348 // logical widths as we cleared the bits without computing them. |
| 340 // (see calcWidthArray above.) This optimization is preferred to always | 349 // (see calcWidthArray above.) This optimization is preferred to always |
| 341 // computing the logical widths we never intended to use. | 350 // computing the logical widths we never intended to use. |
| 342 m_table->recalcSectionsIfNeeded(); | 351 m_table->recalcSectionsIfNeeded(); |
| 343 m_table->markAllCellsWidthsDirtyAndOrNeedsLayout(LayoutTable::MarkDirtyOnly); | 352 m_table->markAllCellsWidthsDirtyAndOrNeedsLayout(LayoutTable::MarkDirtyOnly); |
| 344 } | 353 } |
| 345 | 354 |
| 346 } // namespace blink | 355 } // namespace blink |
| OLD | NEW |