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 |