Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: Source/WebCore/rendering/TextAutosizer.cpp

Issue 11859014: Merge 138111 (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/1364/
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/WebCore/rendering/TextAutosizer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * Copyright (C) 2012 Apple Inc. All rights reserved. 3 * Copyright (C) 2012 Apple Inc. All rights reserved.
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details. 13 * Library General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU Library General Public License 15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to 16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA. 18 * Boston, MA 02110-1301, USA.
19 */ 19 */
20 20
21 #include "config.h" 21 #include "config.h"
22 22
23 #if ENABLE(TEXT_AUTOSIZING) 23 #if ENABLE(TEXT_AUTOSIZING)
24 24
25 #include "TextAutosizer.h" 25 #include "TextAutosizer.h"
26 26
27 #include "Document.h" 27 #include "Document.h"
28 #include "InspectorInstrumentation.h" 28 #include "InspectorInstrumentation.h"
29 #include "IntSize.h"
29 #include "RenderObject.h" 30 #include "RenderObject.h"
30 #include "RenderStyle.h" 31 #include "RenderStyle.h"
31 #include "RenderText.h" 32 #include "RenderText.h"
32 #include "RenderView.h" 33 #include "RenderView.h"
33 #include "Settings.h" 34 #include "Settings.h"
34 #include "StyleInheritedData.h" 35 #include "StyleInheritedData.h"
35 36
36 #include <algorithm> 37 #include <algorithm>
37 38
38 namespace WebCore { 39 namespace WebCore {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 if (!frame->view()->isInChildFrameWithFrameFlattening()) 79 if (!frame->view()->isInChildFrameWithFrameFlattening())
79 windowInfo.minLayoutSize = windowInfo.minLayoutSize.shrunkTo(frame-> view()->layoutSize()); 80 windowInfo.minLayoutSize = windowInfo.minLayoutSize.shrunkTo(frame-> view()->layoutSize());
80 } 81 }
81 82
82 // The layoutRoot could be neither a container nor a cluster, so walk up the tree till we find each of these. 83 // The layoutRoot could be neither a container nor a cluster, so walk up the tree till we find each of these.
83 RenderBlock* container = layoutRoot->isRenderBlock() ? toRenderBlock(layoutR oot) : layoutRoot->containingBlock(); 84 RenderBlock* container = layoutRoot->isRenderBlock() ? toRenderBlock(layoutR oot) : layoutRoot->containingBlock();
84 while (container && !isAutosizingContainer(container)) 85 while (container && !isAutosizingContainer(container))
85 container = container->containingBlock(); 86 container = container->containingBlock();
86 87
87 RenderBlock* cluster = container; 88 RenderBlock* cluster = container;
88 while (cluster && (!isAutosizingContainer(cluster) || !isAutosizingCluster(c luster))) 89 while (cluster && !isAutosizingCluster(cluster))
89 cluster = cluster->containingBlock(); 90 cluster = cluster->containingBlock();
90 91
91 processCluster(cluster, container, layoutRoot, windowInfo); 92 processCluster(cluster, container, layoutRoot, windowInfo);
92 return true; 93 return true;
93 } 94 }
94 95
95 void TextAutosizer::processCluster(RenderBlock* cluster, RenderBlock* container, RenderObject* subtreeRoot, const TextAutosizingWindowInfo& windowInfo) 96 void TextAutosizer::processCluster(RenderBlock* cluster, RenderBlock* container, RenderObject* subtreeRoot, const TextAutosizingWindowInfo& windowInfo)
96 { 97 {
97 ASSERT(isAutosizingCluster(cluster));
98
99 // Many pages set a max-width on their content. So especially for the 98 // Many pages set a max-width on their content. So especially for the
100 // RenderView, instead of just taking the width of |cluster| we find 99 // RenderView, instead of just taking the width of |cluster| we find
101 // the lowest common ancestor of the first and last descendant text node of 100 // the lowest common ancestor of the first and last descendant text node of
102 // the cluster (i.e. the deepest wrapper block that contains all the text), 101 // the cluster (i.e. the deepest wrapper block that contains all the text),
103 // and use its width instead. 102 // and use its width instead.
104 const RenderBlock* lowestCommonAncestor = findDeepestBlockContainingAllText( cluster); 103 const RenderBlock* blockContainingAllText = findDeepestBlockContainingAllTex t(cluster);
105 float commonAncestorWidth = lowestCommonAncestor->contentLogicalWidth(); 104 float textWidth = blockContainingAllText->contentLogicalWidth();
106 105
107 float multiplier = 1; 106 float multiplier = 1;
108 if (clusterShouldBeAutosized(lowestCommonAncestor, commonAncestorWidth)) { 107 if (clusterShouldBeAutosized(blockContainingAllText, textWidth)) {
109 int logicalWindowWidth = cluster->isHorizontalWritingMode() ? windowInfo .windowSize.width() : windowInfo.windowSize.height(); 108 int logicalWindowWidth = cluster->isHorizontalWritingMode() ? windowInfo .windowSize.width() : windowInfo.windowSize.height();
110 int logicalLayoutWidth = cluster->isHorizontalWritingMode() ? windowInfo .minLayoutSize.width() : windowInfo.minLayoutSize.height(); 109 int logicalLayoutWidth = cluster->isHorizontalWritingMode() ? windowInfo .minLayoutSize.width() : windowInfo.minLayoutSize.height();
111 // Ignore box width in excess of the layout width, to avoid extreme mult ipliers. 110 // Ignore box width in excess of the layout width, to avoid extreme mult ipliers.
112 float logicalClusterWidth = std::min<float>(commonAncestorWidth, logical LayoutWidth); 111 float logicalClusterWidth = std::min<float>(textWidth, logicalLayoutWidt h);
113 112
114 multiplier = logicalClusterWidth / logicalWindowWidth; 113 multiplier = logicalClusterWidth / logicalWindowWidth;
115 multiplier *= m_document->settings()->textAutosizingFontScaleFactor(); 114 multiplier *= m_document->settings()->textAutosizingFontScaleFactor();
116 multiplier = std::max(1.0f, multiplier); 115 multiplier = std::max(1.0f, multiplier);
117 } 116 }
118 117
119 processContainer(multiplier, container, subtreeRoot, windowInfo); 118 processContainer(multiplier, container, blockContainingAllText, subtreeRoot, windowInfo);
120 } 119 }
121 120
122 void TextAutosizer::processContainer(float multiplier, RenderBlock* container, R enderObject* subtreeRoot, const TextAutosizingWindowInfo& windowInfo) 121 void TextAutosizer::processContainer(float multiplier, RenderBlock* container, c onst RenderBlock* blockContainingAllText, RenderObject* subtreeRoot, const TextA utosizingWindowInfo& windowInfo)
123 { 122 {
124 ASSERT(isAutosizingContainer(container)); 123 ASSERT(isAutosizingContainer(container));
125 124
126 float localMultiplier = containerShouldbeAutosized(container) ? multiplier: 1; 125 float localMultiplier = containerShouldBeAutosized(container) ? multiplier: 1;
127 126
128 RenderObject* descendant = nextInPreOrderSkippingDescendantsOfContainers(sub treeRoot, subtreeRoot); 127 RenderObject* descendant = nextInPreOrderSkippingDescendantsOfContainers(sub treeRoot, subtreeRoot);
129 while (descendant) { 128 while (descendant) {
130 if (descendant->isText()) { 129 if (descendant->isText()) {
131 if (localMultiplier != descendant->style()->textAutosizingMultiplier ()) { 130 if (localMultiplier != descendant->style()->textAutosizingMultiplier ()) {
132 setMultiplier(descendant, localMultiplier); 131 setMultiplier(descendant, localMultiplier);
133 setMultiplier(descendant->parent(), localMultiplier); // Parent does line spacing. 132 setMultiplier(descendant->parent(), localMultiplier); // Parent does line spacing.
134 } 133 }
135 // FIXME: Increase list marker size proportionately. 134 // FIXME: Increase list marker size proportionately.
136 } else if (isAutosizingContainer(descendant)) { 135 } else if (isAutosizingContainer(descendant)) {
137 RenderBlock* descendantBlock = toRenderBlock(descendant); 136 RenderBlock* descendantBlock = toRenderBlock(descendant);
138 if (isAutosizingCluster(descendantBlock)) 137 if (isAutosizingCluster(descendantBlock, blockContainingAllText))
139 processCluster(descendantBlock, descendantBlock, descendantBlock , windowInfo); 138 processCluster(descendantBlock, descendantBlock, descendantBlock , windowInfo);
140 else 139 else
141 processContainer(multiplier, descendantBlock, descendantBlock, w indowInfo); 140 processContainer(multiplier, descendantBlock, blockContainingAll Text, descendantBlock, windowInfo);
142 } 141 }
143 descendant = nextInPreOrderSkippingDescendantsOfContainers(descendant, s ubtreeRoot); 142 descendant = nextInPreOrderSkippingDescendantsOfContainers(descendant, s ubtreeRoot);
144 } 143 }
145 } 144 }
146 145
147 void TextAutosizer::setMultiplier(RenderObject* renderer, float multiplier) 146 void TextAutosizer::setMultiplier(RenderObject* renderer, float multiplier)
148 { 147 {
149 RefPtr<RenderStyle> newStyle = RenderStyle::clone(renderer->style()); 148 RefPtr<RenderStyle> newStyle = RenderStyle::clone(renderer->style());
150 newStyle->setTextAutosizingMultiplier(multiplier); 149 newStyle->setTextAutosizingMultiplier(multiplier);
151 renderer->setStyle(newStyle.release()); 150 renderer->setStyle(newStyle.release());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 // - Must not be list items, as items in the same list should look consisten t (*). 188 // - Must not be list items, as items in the same list should look consisten t (*).
190 // - Must not be normal list items, as items in the same list should look 189 // - Must not be normal list items, as items in the same list should look
191 // consistent, unless they are floating or position:absolute/fixed. 190 // consistent, unless they are floating or position:absolute/fixed.
192 if (!renderer->isRenderBlock() || (renderer->isInline() && !renderer->style( )->isDisplayReplacedType())) 191 if (!renderer->isRenderBlock() || (renderer->isInline() && !renderer->style( )->isDisplayReplacedType()))
193 return false; 192 return false;
194 if (renderer->isListItem()) 193 if (renderer->isListItem())
195 return renderer->isFloating() || renderer->isOutOfFlowPositioned(); 194 return renderer->isFloating() || renderer->isOutOfFlowPositioned();
196 return true; 195 return true;
197 } 196 }
198 197
199 bool TextAutosizer::isAutosizingCluster(const RenderBlock* renderer) 198 bool TextAutosizer::isAutosizingCluster(const RenderBlock* renderer, const Rende rBlock* parentBlockContainingAllText)
200 { 199 {
201 // "Autosizing clusters" are special autosizing containers within which we 200 // "Autosizing clusters" are special autosizing containers within which we
202 // want to enforce a uniform text size multiplier, in the hopes of making 201 // want to enforce a uniform text size multiplier, in the hopes of making
203 // the major sections of the page look internally consistent. 202 // the major sections of the page look internally consistent.
204 // All their descendents (including other autosizing containers) must share 203 // All their descendants (including other autosizing containers) must share
205 // the same multiplier, except for subtrees which are themselves clusters, 204 // the same multiplier, except for subtrees which are themselves clusters,
206 // and some of their descendent containers might not be autosized at all 205 // and some of their descendant containers might not be autosized at all
207 // (for example if their height is constrained). 206 // (for example if their height is constrained).
208 // Additionally, clusterShouldBeAutosized requires each cluster to contain a 207 // Additionally, clusterShouldBeAutosized requires each cluster to contain a
209 // minimum amount of text, without which it won't be autosized. 208 // minimum amount of text, without which it won't be autosized.
210 // 209 //
211 // Clusters are chosen using very similar criteria to CSS flow roots, aka 210 // Clusters are chosen using very similar criteria to CSS flow roots, aka
212 // block formatting contexts (http://w3.org/TR/css3-box/#flow-root), since 211 // block formatting contexts (http://w3.org/TR/css3-box/#flow-root), since
213 // flow roots correspond to box containers that behave somewhat 212 // flow roots correspond to box containers that behave somewhat
214 // independently from their parent (for example they don't overlap floats). 213 // independently from their parent (for example they don't overlap floats).
215 // The definition of a flow flow root also conveniently includes most of the 214 // The definition of a flow root also conveniently includes most of the
216 // ways that a box and its children can have significantly different width 215 // ways that a box and its children can have significantly different width
217 // from the box's parent (we want to avoid having significantly different 216 // from the box's parent (we want to avoid having significantly different
218 // width blocks within a cluster, since the narrower blocks would end up 217 // width blocks within a cluster, since the narrower blocks would end up
219 // larger than would otherwise be necessary). 218 // larger than would otherwise be necessary).
219 // Additionally, any containers that are wider than the |blockContainingAllT ext|
220 // of their enclosing cluster also become clusters, since they need special
221 // treatment due to their width.
220 ASSERT(isAutosizingContainer(renderer)); 222 ASSERT(isAutosizingContainer(renderer));
221 223
222 return renderer->isRenderView() 224 return renderer->isRenderView()
223 || renderer->isFloating() 225 || renderer->isFloating()
224 || renderer->isOutOfFlowPositioned() 226 || renderer->isOutOfFlowPositioned()
225 || renderer->isTableCell() 227 || renderer->isTableCell()
226 || renderer->isTableCaption() 228 || renderer->isTableCaption()
227 || renderer->isFlexibleBoxIncludingDeprecated() 229 || renderer->isFlexibleBoxIncludingDeprecated()
228 || renderer->hasColumns() 230 || renderer->hasColumns()
229 || renderer->containingBlock()->isHorizontalWritingMode() != renderer->i sHorizontalWritingMode() 231 || renderer->containingBlock()->isHorizontalWritingMode() != renderer->i sHorizontalWritingMode()
230 || renderer->style()->isDisplayReplacedType(); 232 || renderer->style()->isDisplayReplacedType()
233 || (parentBlockContainingAllText
234 && renderer->contentLogicalWidth() > parentBlockContainingAllText->c ontentLogicalWidth());
231 // FIXME: Tables need special handling to multiply all their columns by 235 // FIXME: Tables need special handling to multiply all their columns by
232 // the same amount even if they're different widths; so do hasColumns() 236 // the same amount even if they're different widths; so do hasColumns()
233 // containers, and probably flexboxes... 237 // containers, and probably flexboxes...
234 } 238 }
235 239
240 bool TextAutosizer::isAutosizingCluster(const RenderObject* object)
241 {
242 return isAutosizingContainer(object) && isAutosizingCluster(toRenderBlock(ob ject), 0);
243 }
244
236 static bool contentHeightIsConstrained(const RenderBlock* container) 245 static bool contentHeightIsConstrained(const RenderBlock* container)
237 { 246 {
238 // FIXME: Propagate constrainedness down the tree, to avoid inefficiently wa lking back up from each box. 247 // FIXME: Propagate constrainedness down the tree, to avoid inefficiently wa lking back up from each box.
239 // FIXME: This code needs to take into account vertical writing modes. 248 // FIXME: This code needs to take into account vertical writing modes.
240 // FIXME: Consider additional heuristics, such as ignoring fixed heights if the content is already overflowing before autosizing kicks in. 249 // FIXME: Consider additional heuristics, such as ignoring fixed heights if the content is already overflowing before autosizing kicks in.
241 for (; container; container = container->containingBlock()) { 250 for (; container; container = container->containingBlock()) {
242 RenderStyle* style = container->style(); 251 RenderStyle* style = container->style();
243 if (style->overflowY() >= OSCROLL) 252 if (style->overflowY() >= OSCROLL)
244 return false; 253 return false;
245 if (style->height().isSpecified() || style->maxHeight().isSpecified()) { 254 if (style->height().isSpecified() || style->maxHeight().isSpecified()) {
246 // Some sites (e.g. wikipedia) set their html and/or body elements t o height:100%, 255 // Some sites (e.g. wikipedia) set their html and/or body elements t o height:100%,
247 // without intending to constrain the height of the content within t hem. 256 // without intending to constrain the height of the content within t hem.
248 return !container->isRoot() && !container->isBody(); 257 return !container->isRoot() && !container->isBody();
249 } 258 }
250 if (container->isFloatingOrOutOfFlowPositioned()) 259 if (container->isFloatingOrOutOfFlowPositioned())
251 return false; 260 return false;
252 } 261 }
253 return false; 262 return false;
254 } 263 }
255 264
256 bool TextAutosizer::containerShouldbeAutosized(const RenderBlock* container) 265 bool TextAutosizer::containerShouldBeAutosized(const RenderBlock* container)
257 { 266 {
258 // Don't autosize block-level text that can't wrap (as it's likely to 267 // Don't autosize block-level text that can't wrap (as it's likely to
259 // expand sideways and break the page's layout). 268 // expand sideways and break the page's layout).
260 if (!container->style()->autoWrap()) 269 if (!container->style()->autoWrap())
261 return false; 270 return false;
262 271
263 return !contentHeightIsConstrained(container); 272 return !contentHeightIsConstrained(container);
264 } 273 }
265 274
266 bool TextAutosizer::clusterShouldBeAutosized(const RenderBlock* lowestCommonAnce stor, float commonAncestorWidth) 275 bool TextAutosizer::clusterShouldBeAutosized(const RenderBlock* blockContainingA llText, float blockWidth)
267 { 276 {
268 // Don't autosize clusters that contain less than 4 lines of text (in 277 // Don't autosize clusters that contain less than 4 lines of text (in
269 // practice less lines are required, since measureDescendantTextWidth 278 // practice less lines are required, since measureDescendantTextWidth
270 // assumes that characters are 1em wide, but most characters are narrower 279 // assumes that characters are 1em wide, but most characters are narrower
271 // than that, so we're overestimating their contribution to the linecount). 280 // than that, so we're overestimating their contribution to the linecount).
272 // 281 //
273 // This is to reduce the likelihood of autosizing things like headers and 282 // This is to reduce the likelihood of autosizing things like headers and
274 // footers, which can be quite visually distracting. The rationale is that 283 // footers, which can be quite visually distracting. The rationale is that
275 // if a cluster contains very few lines of text then it's ok to have to zoom 284 // if a cluster contains very few lines of text then it's ok to have to zoom
276 // in and pan from side to side to read each line, since if there are very 285 // in and pan from side to side to read each line, since if there are very
277 // few lines of text you'll only need to pan across once or twice. 286 // few lines of text you'll only need to pan across once or twice.
278 const float minLinesOfText = 4; 287 const float minLinesOfText = 4;
279 float minTextWidth = commonAncestorWidth * minLinesOfText; 288 float minTextWidth = blockWidth * minLinesOfText;
280 float textWidth = 0; 289 float textWidth = 0;
281 measureDescendantTextWidth(lowestCommonAncestor, minTextWidth, textWidth); 290 measureDescendantTextWidth(blockContainingAllText, blockContainingAllText, m inTextWidth, textWidth);
282 if (textWidth >= minTextWidth) 291 if (textWidth >= minTextWidth)
283 return true; 292 return true;
284 return false; 293 return false;
285 } 294 }
286 295
287 void TextAutosizer::measureDescendantTextWidth(const RenderBlock* container, flo at minTextWidth, float& textWidth) 296 void TextAutosizer::measureDescendantTextWidth(const RenderBlock* container, con st RenderBlock* blockContainingAllText, float minTextWidth, float& textWidth)
288 { 297 {
289 bool skipLocalText = !containerShouldbeAutosized(container); 298 bool skipLocalText = !containerShouldBeAutosized(container);
290 299
291 RenderObject* descendant = nextInPreOrderSkippingDescendantsOfContainers(con tainer, container); 300 RenderObject* descendant = nextInPreOrderSkippingDescendantsOfContainers(con tainer, container);
292 while (descendant) { 301 while (descendant) {
293 if (!skipLocalText && descendant->isText()) { 302 if (!skipLocalText && descendant->isText()) {
294 textWidth += toRenderText(descendant)->renderedTextLength() * descen dant->style()->specifiedFontSize(); 303 textWidth += toRenderText(descendant)->renderedTextLength() * descen dant->style()->specifiedFontSize();
295 } else if (isAutosizingContainer(descendant)) { 304 } else if (isAutosizingContainer(descendant)) {
296 RenderBlock* descendantBlock = toRenderBlock(descendant); 305 RenderBlock* descendantBlock = toRenderBlock(descendant);
297 if (!isAutosizingCluster(descendantBlock)) 306 if (!isAutosizingCluster(descendantBlock, blockContainingAllText))
298 measureDescendantTextWidth(descendantBlock, minTextWidth, textWi dth); 307 measureDescendantTextWidth(descendantBlock, blockContainingAllTe xt, minTextWidth, textWidth);
299 } 308 }
300 if (textWidth >= minTextWidth) 309 if (textWidth >= minTextWidth)
301 return; 310 return;
302 descendant = nextInPreOrderSkippingDescendantsOfContainers(descendant, c ontainer); 311 descendant = nextInPreOrderSkippingDescendantsOfContainers(descendant, c ontainer);
303 } 312 }
304 } 313 }
305 314
306 RenderObject* TextAutosizer::nextInPreOrderSkippingDescendantsOfContainers(const RenderObject* current, const RenderObject* stayWithin) 315 RenderObject* TextAutosizer::nextInPreOrderSkippingDescendantsOfContainers(const RenderObject* current, const RenderObject* stayWithin)
307 { 316 {
308 if (current == stayWithin || !isAutosizingContainer(current)) 317 if (current == stayWithin || !isAutosizingContainer(current))
309 for (RenderObject* child = current->firstChild(); child; child = child-> nextSibling()) 318 for (RenderObject* child = current->firstChild(); child; child = child-> nextSibling())
310 return child; 319 return child;
311 320
312 for (const RenderObject* ancestor = current; ancestor; ancestor = ancestor-> parent()) { 321 for (const RenderObject* ancestor = current; ancestor; ancestor = ancestor-> parent()) {
313 if (ancestor == stayWithin) 322 if (ancestor == stayWithin)
314 return 0; 323 return 0;
315 for (RenderObject* sibling = ancestor->nextSibling(); sibling; sibling = sibling->nextSibling()) 324 for (RenderObject* sibling = ancestor->nextSibling(); sibling; sibling = sibling->nextSibling())
316 return sibling; 325 return sibling;
317 } 326 }
318 327
319 return 0; 328 return 0;
320 } 329 }
321 330
322 const RenderBlock* TextAutosizer::findDeepestBlockContainingAllText(const Render Block* cluster) 331 const RenderBlock* TextAutosizer::findDeepestBlockContainingAllText(const Render Block* cluster)
323 { 332 {
324 ASSERT(isAutosizingCluster(cluster));
325
326 size_t firstDepth = 0; 333 size_t firstDepth = 0;
327 const RenderObject* firstTextLeaf = findFirstTextLeafNotInCluster(cluster, f irstDepth, FirstToLast); 334 const RenderObject* firstTextLeaf = findFirstTextLeafNotInCluster(cluster, f irstDepth, FirstToLast);
328 if (!firstTextLeaf) 335 if (!firstTextLeaf)
329 return cluster; 336 return cluster;
330 337
331 size_t lastDepth = 0; 338 size_t lastDepth = 0;
332 const RenderObject* lastTextLeaf = findFirstTextLeafNotInCluster(cluster, la stDepth, LastToFirst); 339 const RenderObject* lastTextLeaf = findFirstTextLeafNotInCluster(cluster, la stDepth, LastToFirst);
333 ASSERT(lastTextLeaf); 340 ASSERT(lastTextLeaf);
334 341
335 // Equalize the depths if necessary. Only one of the while loops below will get executed. 342 // Equalize the depths if necessary. Only one of the while loops below will get executed.
(...skipping 28 matching lines...) Expand all
364 } 371 }
365 372
366 const RenderObject* TextAutosizer::findFirstTextLeafNotInCluster(const RenderObj ect* parent, size_t& depth, TraversalDirection direction) 373 const RenderObject* TextAutosizer::findFirstTextLeafNotInCluster(const RenderObj ect* parent, size_t& depth, TraversalDirection direction)
367 { 374 {
368 if (parent->isEmpty()) 375 if (parent->isEmpty())
369 return parent->isText() ? parent : 0; 376 return parent->isText() ? parent : 0;
370 377
371 ++depth; 378 ++depth;
372 const RenderObject* child = (direction == FirstToLast) ? parent->firstChild( ) : parent->lastChild(); 379 const RenderObject* child = (direction == FirstToLast) ? parent->firstChild( ) : parent->lastChild();
373 while (child) { 380 while (child) {
374 if (!isAutosizingContainer(child) || !isAutosizingCluster(toRenderBlock( child))) { 381 if (!isAutosizingCluster(child)) {
375 const RenderObject* leaf = findFirstTextLeafNotInCluster(child, dept h, direction); 382 const RenderObject* leaf = findFirstTextLeafNotInCluster(child, dept h, direction);
376 if (leaf) 383 if (leaf)
377 return leaf; 384 return leaf;
378 } 385 }
379 child = (direction == FirstToLast) ? child->nextSibling() : child->previ ousSibling(); 386 child = (direction == FirstToLast) ? child->nextSibling() : child->previ ousSibling();
380 } 387 }
381 --depth; 388 --depth;
382 389
383 return 0; 390 return 0;
384 } 391 }
385 392
386 } // namespace WebCore 393 } // namespace WebCore
387 394
388 #endif // ENABLE(TEXT_AUTOSIZING) 395 #endif // ENABLE(TEXT_AUTOSIZING)
OLDNEW
« no previous file with comments | « Source/WebCore/rendering/TextAutosizer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698