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

Side by Side Diff: Source/core/rendering/FastTextAutosizer.cpp

Issue 180743004: Disable FTA when max multiplier is 1. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 9 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 return parent; 56 return parent;
57 } 57 }
58 return 0; 58 return 0;
59 } 59 }
60 60
61 FastTextAutosizer::FastTextAutosizer(const Document* document) 61 FastTextAutosizer::FastTextAutosizer(const Document* document)
62 : m_document(document) 62 : m_document(document)
63 , m_frameWidth(0) 63 , m_frameWidth(0)
64 , m_layoutWidth(0) 64 , m_layoutWidth(0)
65 , m_baseMultiplier(0) 65 , m_baseMultiplier(0)
66 , m_pageNeedsAutosizing(PageNeedsAutosizing_Unknown)
66 , m_firstBlock(0) 67 , m_firstBlock(0)
67 #ifndef NDEBUG 68 #ifndef NDEBUG
68 , m_renderViewInfoPrepared(false) 69 , m_renderViewInfoPrepared(false)
69 , m_blocksThatHaveBegunLayout() 70 , m_blocksThatHaveBegunLayout()
70 #endif 71 #endif
71 , m_superclusters() 72 , m_superclusters()
72 , m_clusterStack() 73 , m_clusterStack()
73 , m_fingerprintMapper() 74 , m_fingerprintMapper()
74 { 75 {
75 } 76 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 } 115 }
115 116
116 void FastTextAutosizer::beginLayout(RenderBlock* block) 117 void FastTextAutosizer::beginLayout(RenderBlock* block)
117 { 118 {
118 ASSERT(enabled()); 119 ASSERT(enabled());
119 #ifndef NDEBUG 120 #ifndef NDEBUG
120 m_blocksThatHaveBegunLayout.add(block); 121 m_blocksThatHaveBegunLayout.add(block);
121 #endif 122 #endif
122 123
123 if (!m_firstBlock) { 124 if (!m_firstBlock) {
124 prepareRenderViewInfo(); 125 m_firstBlock = block;
125 prepareClusterStack(block->parent()); 126 prepareClusterStack(block->parent());
126 m_firstBlock = block;
127 } else if (block == currentCluster()->m_root) { 127 } else if (block == currentCluster()->m_root) {
128 // Ignore beginLayout on the same block twice. 128 // Ignore beginLayout on the same block twice.
129 // This can happen with paginated overflow. 129 // This can happen with paginated overflow.
130 return; 130 return;
131 } 131 }
132 132
133 if (Cluster* cluster = maybeCreateCluster(block)) { 133 if (Cluster* cluster = maybeCreateCluster(block)) {
134 m_clusterStack.append(adoptPtr(cluster)); 134 m_clusterStack.append(adoptPtr(cluster));
135 if (block->isTable()) 135 if (block->isTable())
136 inflateTable(toRenderTable(block)); 136 inflateTable(toRenderTable(block));
137 } 137 }
138 138
139 if (block->childrenInline()) 139 if (block->childrenInline())
140 inflate(block); 140 inflate(block);
141 } 141 }
142 142
143 bool FastTextAutosizer::isInLayout() const
144 {
145 return !!m_firstBlock;
146 }
147
143 void FastTextAutosizer::inflateListItem(RenderListItem* listItem, RenderListMark er* listItemMarker) 148 void FastTextAutosizer::inflateListItem(RenderListItem* listItem, RenderListMark er* listItemMarker)
144 { 149 {
145 if (!enabled()) 150 if (!enabled())
146 return; 151 return;
147 ASSERT(listItem && listItemMarker); 152 ASSERT(listItem && listItemMarker);
148 #ifndef NDEBUG 153 #ifndef NDEBUG
149 m_blocksThatHaveBegunLayout.add(listItem); 154 m_blocksThatHaveBegunLayout.add(listItem);
150 #endif 155 #endif
151 // Force the LI to be inside the DBCAT when computing the multiplier. 156 // Force the LI to be inside the DBCAT when computing the multiplier.
152 // This guarantees that the DBCAT has entered layout, so we can ask for its width. 157 // This guarantees that the DBCAT has entered layout, so we can ask for its width.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 } 200 }
196 201
197 void FastTextAutosizer::endLayout(RenderBlock* block) 202 void FastTextAutosizer::endLayout(RenderBlock* block)
198 { 203 {
199 ASSERT(enabled()); 204 ASSERT(enabled());
200 205
201 if (currentCluster()->m_root == block) 206 if (currentCluster()->m_root == block)
202 m_clusterStack.removeLast(); 207 m_clusterStack.removeLast();
203 208
204 if (block == m_firstBlock) { 209 if (block == m_firstBlock) {
205 m_firstBlock = 0; 210 m_firstBlock = 0;
pdr. 2014/03/01 05:16:43 Should we reset m_pageNeedsAutosizing here?
206 m_clusterStack.clear(); 211 m_clusterStack.clear();
207 m_superclusters.clear(); 212 m_superclusters.clear();
208 #ifndef NDEBUG 213 #ifndef NDEBUG
209 m_blocksThatHaveBegunLayout.clear(); 214 m_blocksThatHaveBegunLayout.clear();
210 #endif 215 #endif
211 } 216 }
212 } 217 }
213 218
214 void FastTextAutosizer::inflate(RenderBlock* block) 219 void FastTextAutosizer::inflate(RenderBlock* block)
215 { 220 {
216 Cluster* cluster = currentCluster(); 221 Cluster* cluster = currentCluster();
217 float multiplier = 0; 222 float multiplier = 0;
218 for (RenderObject* descendant = nextChildSkippingChildrenOfBlocks(block, blo ck); descendant; descendant = nextChildSkippingChildrenOfBlocks(descendant, bloc k)) { 223 for (RenderObject* descendant = nextChildSkippingChildrenOfBlocks(block, blo ck); descendant; descendant = nextChildSkippingChildrenOfBlocks(descendant, bloc k)) {
219 if (descendant->isText()) { 224 if (descendant->isText()) {
220 // We only calculate this multiplier on-demand to ensure the parent block of this text 225 // We only calculate this multiplier on-demand to ensure the parent block of this text
221 // has entered layout. 226 // has entered layout.
222 if (!multiplier) 227 if (!multiplier)
223 multiplier = cluster->m_autosize ? clusterMultiplier(cluster) : 1.0f; 228 multiplier = cluster->m_autosize ? clusterMultiplier(cluster) : 1.0f;
224 applyMultiplier(descendant, multiplier); 229 applyMultiplier(descendant, multiplier);
225 applyMultiplier(descendant->parent(), multiplier); // Parent handles line spacing. 230 applyMultiplier(descendant->parent(), multiplier); // Parent handles line spacing.
226 } 231 }
227 } 232 }
228 } 233 }
229 234
230 bool FastTextAutosizer::enabled() 235 bool FastTextAutosizer::enabled()
231 { 236 {
232 if (!m_document->settings() || !m_document->page() || m_document->printing() ) 237 if (!m_document->settings()
238 || !m_document->page()
239 || m_document->printing()
240 || !m_document->settings()->textAutosizingEnabled())
233 return false; 241 return false;
234 242
235 return m_document->settings()->textAutosizingEnabled(); 243 if (m_pageNeedsAutosizing == PageNeedsAutosizing_Unknown)
244 updateRenderViewInfo();
245
246 if (m_pageNeedsAutosizing == PageNeedsAutosizing_No)
247 return false;
248
249 return true;
236 } 250 }
237 251
238 void FastTextAutosizer::prepareRenderViewInfo() 252 void FastTextAutosizer::updateRenderViewInfo()
239 { 253 {
254 if (!m_document->settings()
pdr. 2014/03/01 05:16:43 Having these checks in two places doesn't seem rig
255 || !m_document->page()
256 || m_document->printing()
257 || !m_document->settings()->textAutosizingEnabled())
258 return;
259
240 RenderView* renderView = toRenderView(m_document->renderer()); 260 RenderView* renderView = toRenderView(m_document->renderer());
241 bool horizontalWritingMode = isHorizontalWritingMode(renderView->style()->wr itingMode()); 261 bool horizontalWritingMode = isHorizontalWritingMode(renderView->style()->wr itingMode());
242 262
243 LocalFrame* mainFrame = m_document->page()->mainFrame(); 263 LocalFrame* mainFrame = m_document->page()->mainFrame();
244 IntSize frameSize = m_document->settings()->textAutosizingWindowSizeOverride (); 264 IntSize frameSize = m_document->settings()->textAutosizingWindowSizeOverride ();
245 if (frameSize.isEmpty()) 265 if (frameSize.isEmpty())
246 frameSize = mainFrame->view()->unscaledVisibleContentSize(IncludeScrollb ars); 266 frameSize = mainFrame->view()->unscaledVisibleContentSize(IncludeScrollb ars);
247 m_frameWidth = horizontalWritingMode ? frameSize.width() : frameSize.height( ); 267 m_frameWidth = horizontalWritingMode ? frameSize.width() : frameSize.height( );
248 268
249 IntSize layoutSize = m_document->page()->mainFrame()->view()->layoutSize(); 269 IntSize layoutSize = m_document->page()->mainFrame()->view()->layoutSize();
250 m_layoutWidth = horizontalWritingMode ? layoutSize.width() : layoutSize.heig ht(); 270 m_layoutWidth = horizontalWritingMode ? layoutSize.width() : layoutSize.heig ht();
251 271
252 // Compute the base font scale multiplier based on device and accessibility settings. 272 // Compute the base font scale multiplier based on device and accessibility settings.
253 m_baseMultiplier = m_document->settings()->accessibilityFontScaleFactor(); 273 m_baseMultiplier = m_document->settings()->accessibilityFontScaleFactor();
254 // If the page has a meta viewport or @viewport, don't apply the device scal e adjustment. 274 // If the page has a meta viewport or @viewport, don't apply the device scal e adjustment.
255 const ViewportDescription& viewportDescription = m_document->page()->mainFra me()->document()->viewportDescription(); 275 const ViewportDescription& viewportDescription = m_document->page()->mainFra me()->document()->viewportDescription();
256 if (!viewportDescription.isSpecifiedByAuthor()) { 276 if (!viewportDescription.isSpecifiedByAuthor()) {
257 float deviceScaleAdjustment = m_document->settings()->deviceScaleAdjustm ent(); 277 float deviceScaleAdjustment = m_document->settings()->deviceScaleAdjustm ent();
258 m_baseMultiplier *= deviceScaleAdjustment; 278 m_baseMultiplier *= deviceScaleAdjustment;
259 } 279 }
280
281 if (m_frameWidth) {
282 m_pageNeedsAutosizing = (m_baseMultiplier * (static_cast<float>(m_layout Width) / m_frameWidth) > 1.0f)
283 ? PageNeedsAutosizing_Yes : PageNeedsAutosizing_No;
284 } else {
285 m_pageNeedsAutosizing = PageNeedsAutosizing_Unknown;
286 }
287
260 #ifndef NDEBUG 288 #ifndef NDEBUG
261 m_renderViewInfoPrepared = true; 289 m_renderViewInfoPrepared = true;
262 #endif 290 #endif
263 } 291 }
264 292
265 bool FastTextAutosizer::isFingerprintingCandidate(const RenderBlock* block) 293 bool FastTextAutosizer::isFingerprintingCandidate(const RenderBlock* block)
266 { 294 {
267 // FIXME: move the logic out of TextAutosizer.cpp into this class. 295 // FIXME: move the logic out of TextAutosizer.cpp into this class.
268 return block->isRenderView() 296 return block->isRenderView()
269 || (TextAutosizer::isAutosizingContainer(block) 297 || (TextAutosizer::isAutosizingContainer(block)
270 && (TextAutosizer::isIndependentDescendant(block) 298 && (TextAutosizer::isIndependentDescendant(block)
271 || mightBeWiderOrNarrowerDescendant(block))); 299 || mightBeWiderOrNarrowerDescendant(block)));
272 } 300 }
273 301
274 bool FastTextAutosizer::clusterWouldHaveEnoughTextToAutosize(const RenderBlock* root, const RenderBlock* widthProvider) 302 bool FastTextAutosizer::clusterWouldHaveEnoughTextToAutosize(const RenderBlock* root, const RenderBlock* widthProvider)
275 { 303 {
276 Cluster hypotheticalCluster(root, true, 0); 304 Cluster hypotheticalCluster(root, true, 0);
277 return clusterHasEnoughTextToAutosize(&hypotheticalCluster, widthProvider); 305 return clusterHasEnoughTextToAutosize(&hypotheticalCluster, widthProvider);
278 } 306 }
279 307
280 bool FastTextAutosizer::clusterHasEnoughTextToAutosize(Cluster* cluster, const R enderBlock* widthProvider) 308 bool FastTextAutosizer::clusterHasEnoughTextToAutosize(Cluster* cluster, const R enderBlock* widthProvider)
281 { 309 {
282 if (cluster->m_hasEnoughTextToAutosize != Unknown) 310 if (cluster->m_hasEnoughTextToAutosize != HasEnoughTextToAutosize_Unknown)
283 return cluster->m_hasEnoughTextToAutosize == Yes; 311 return cluster->m_hasEnoughTextToAutosize == HasEnoughTextToAutosize_Yes ;
284 312
285 const RenderBlock* root = cluster->m_root; 313 const RenderBlock* root = cluster->m_root;
286 if (!widthProvider) 314 if (!widthProvider)
287 widthProvider = clusterWidthProvider(root); 315 widthProvider = clusterWidthProvider(root);
288 316
289 // TextAreas and user-modifiable areas get a free pass to autosize regardles s of text content. 317 // TextAreas and user-modifiable areas get a free pass to autosize regardles s of text content.
290 if (root->isTextArea() || (root->style() && root->style()->userModify() != R EAD_ONLY)) { 318 if (root->isTextArea() || (root->style() && root->style()->userModify() != R EAD_ONLY)) {
291 cluster->m_hasEnoughTextToAutosize = Yes; 319 cluster->m_hasEnoughTextToAutosize = HasEnoughTextToAutosize_Yes;
292 return true; 320 return true;
293 } 321 }
294 322
295 if (!TextAutosizer::containerShouldBeAutosized(root)) { 323 if (!TextAutosizer::containerShouldBeAutosized(root)) {
296 cluster->m_hasEnoughTextToAutosize = No; 324 cluster->m_hasEnoughTextToAutosize = HasEnoughTextToAutosize_No;
297 return false; 325 return false;
298 } 326 }
299 327
300 // 4 lines of text is considered enough to autosize. 328 // 4 lines of text is considered enough to autosize.
301 float minimumTextLengthToAutosize = widthFromBlock(widthProvider) * 4; 329 float minimumTextLengthToAutosize = widthFromBlock(widthProvider) * 4;
302 330
303 float length = 0; 331 float length = 0;
304 RenderObject* descendant = root->nextInPreOrder(root); 332 RenderObject* descendant = root->nextInPreOrder(root);
305 while (descendant) { 333 while (descendant) {
306 if (descendant->isRenderBlock()) { 334 if (descendant->isRenderBlock()) {
307 RenderBlock* block = toRenderBlock(descendant); 335 RenderBlock* block = toRenderBlock(descendant);
308 if (TextAutosizer::isAutosizingContainer(block)) { 336 if (TextAutosizer::isAutosizingContainer(block)) {
309 // Note: Ideally we would check isWiderOrNarrowerDescendant here but we only know that 337 // Note: Ideally we would check isWiderOrNarrowerDescendant here but we only know that
310 // after the block has entered layout, which may not be th e case. 338 // after the block has entered layout, which may not be th e case.
311 bool isAutosizingClusterRoot = TextAutosizer::isIndependentDesce ndant(block); 339 bool isAutosizingClusterRoot = TextAutosizer::isIndependentDesce ndant(block);
312 if (isAutosizingClusterRoot || !TextAutosizer::containerShouldBe Autosized(block)) { 340 if (isAutosizingClusterRoot || !TextAutosizer::containerShouldBe Autosized(block)) {
313 descendant = descendant->nextInPreOrderAfterChildren(root); 341 descendant = descendant->nextInPreOrderAfterChildren(root);
314 continue; 342 continue;
315 } 343 }
316 } 344 }
317 } else if (descendant->isText()) { 345 } else if (descendant->isText()) {
318 // Note: Using text().stripWhiteSpace().length() instead of rendered TextLength() because 346 // Note: Using text().stripWhiteSpace().length() instead of rendered TextLength() because
319 // the lineboxes will not be built until layout. These values can be different. 347 // the lineboxes will not be built until layout. These values can be different.
320 // Note: This is an approximation assuming each character is 1em wid e. 348 // Note: This is an approximation assuming each character is 1em wid e.
321 length += toRenderText(descendant)->text().stripWhiteSpace().length( ) * descendant->style()->specifiedFontSize(); 349 length += toRenderText(descendant)->text().stripWhiteSpace().length( ) * descendant->style()->specifiedFontSize();
322 350
323 if (length >= minimumTextLengthToAutosize) { 351 if (length >= minimumTextLengthToAutosize) {
324 cluster->m_hasEnoughTextToAutosize = Yes; 352 cluster->m_hasEnoughTextToAutosize = HasEnoughTextToAutosize_Yes ;
325 return true; 353 return true;
326 } 354 }
327 } 355 }
328 descendant = descendant->nextInPreOrder(root); 356 descendant = descendant->nextInPreOrder(root);
329 } 357 }
330 358
331 cluster->m_hasEnoughTextToAutosize = No; 359 cluster->m_hasEnoughTextToAutosize = HasEnoughTextToAutosize_No;
332 return false; 360 return false;
333 } 361 }
334 362
335 FastTextAutosizer::Fingerprint FastTextAutosizer::getFingerprint(const RenderObj ect* renderer) 363 FastTextAutosizer::Fingerprint FastTextAutosizer::getFingerprint(const RenderObj ect* renderer)
336 { 364 {
337 Fingerprint result = m_fingerprintMapper.get(renderer); 365 Fingerprint result = m_fingerprintMapper.get(renderer);
338 if (!result) { 366 if (!result) {
339 result = computeFingerprint(renderer); 367 result = computeFingerprint(renderer);
340 m_fingerprintMapper.add(renderer, result); 368 m_fingerprintMapper.add(renderer, result);
341 } 369 }
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 539
512 float FastTextAutosizer::multiplierFromBlock(const RenderBlock* block) 540 float FastTextAutosizer::multiplierFromBlock(const RenderBlock* block)
513 { 541 {
514 // If block->needsLayout() is false, it does not need to be in m_blocksThatH aveBegunLayout. 542 // If block->needsLayout() is false, it does not need to be in m_blocksThatH aveBegunLayout.
515 // This can happen during layout of a positioned object if the cluster's DBC AT is deeper 543 // This can happen during layout of a positioned object if the cluster's DBC AT is deeper
516 // than the positioned object's containing block, and wasn't marked as needi ng layout. 544 // than the positioned object's containing block, and wasn't marked as needi ng layout.
517 ASSERT(m_blocksThatHaveBegunLayout.contains(block) || !block->needsLayout()) ; 545 ASSERT(m_blocksThatHaveBegunLayout.contains(block) || !block->needsLayout()) ;
518 546
519 // Block width, in CSS pixels. 547 // Block width, in CSS pixels.
520 float blockWidth = widthFromBlock(block); 548 float blockWidth = widthFromBlock(block);
521 float multiplier = min(blockWidth, static_cast<float>(m_layoutWidth)) / m_fr ameWidth; 549 float multiplier = m_frameWidth ? min(blockWidth, static_cast<float>(m_layou tWidth)) / m_frameWidth : 1.0f;
522 550
523 return max(m_baseMultiplier * multiplier, 1.0f); 551 return max(m_baseMultiplier * multiplier, 1.0f);
524 } 552 }
525 553
526 const RenderBlock* FastTextAutosizer::deepestBlockContainingAllText(Cluster* clu ster) 554 const RenderBlock* FastTextAutosizer::deepestBlockContainingAllText(Cluster* clu ster)
527 { 555 {
528 if (!cluster->m_deepestBlockContainingAllText) 556 if (!cluster->m_deepestBlockContainingAllText)
529 cluster->m_deepestBlockContainingAllText = deepestBlockContainingAllText (cluster->m_root); 557 cluster->m_deepestBlockContainingAllText = deepestBlockContainingAllText (cluster->m_root);
530 558
531 return cluster->m_deepestBlockContainingAllText; 559 return cluster->m_deepestBlockContainingAllText;
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 return *m_blocksForFingerprint.get(fingerprint); 724 return *m_blocksForFingerprint.get(fingerprint);
697 } 725 }
698 726
699 RenderObject* FastTextAutosizer::nextChildSkippingChildrenOfBlocks(const RenderO bject* current, const RenderObject* stayWithin) 727 RenderObject* FastTextAutosizer::nextChildSkippingChildrenOfBlocks(const RenderO bject* current, const RenderObject* stayWithin)
700 { 728 {
701 if (current == stayWithin || !current->isRenderBlock()) 729 if (current == stayWithin || !current->isRenderBlock())
702 return current->nextInPreOrder(stayWithin); 730 return current->nextInPreOrder(stayWithin);
703 return current->nextInPreOrderAfterChildren(stayWithin); 731 return current->nextInPreOrderAfterChildren(stayWithin);
704 } 732 }
705 733
734 FastTextAutosizer::LayoutScope::LayoutScope(RenderBlock* block)
735 : m_textAutosizer(block->document().fastTextAutosizer())
736 , m_block(block)
737 {
738 if (m_textAutosizer) {
739 if (!m_textAutosizer->isInLayout())
740 m_textAutosizer->updateRenderViewInfo();
pdr. 2014/03/01 05:16:43 Won't the enabled check below handle calling updat
741
742 if (m_textAutosizer->enabled())
743 m_textAutosizer->beginLayout(m_block);
744 else
745 m_textAutosizer = 0;
746 }
747 }
748
749 FastTextAutosizer::LayoutScope::~LayoutScope()
750 {
751 if (m_textAutosizer)
752 m_textAutosizer->endLayout(m_block);
753 }
754
706 } // namespace WebCore 755 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698