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

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: Rebaseline. 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
« no previous file with comments | « Source/core/rendering/FastTextAutosizer.h ('k') | Source/core/rendering/RenderBlock.cpp » ('j') | 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) 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_pageAutosizingStatus(PageAutosizingStatusUnknown)
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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 #ifndef NDEBUG 109 #ifndef NDEBUG
109 m_blocksThatHaveBegunLayout.add(block); 110 m_blocksThatHaveBegunLayout.add(block);
110 #endif 111 #endif
111 if (Cluster* cluster = maybeCreateCluster(block)) 112 if (Cluster* cluster = maybeCreateCluster(block))
112 m_clusterStack.append(adoptPtr(cluster)); 113 m_clusterStack.append(adoptPtr(cluster));
113 } 114 }
114 } 115 }
115 116
116 void FastTextAutosizer::beginLayout(RenderBlock* block) 117 void FastTextAutosizer::beginLayout(RenderBlock* block)
117 { 118 {
118 ASSERT(enabled()); 119 ASSERT(enabled() && m_pageAutosizingStatus == PageNeedsAutosizing);
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() && block->firstChild()) 139 if (block->childrenInline() && block->firstChild())
140 inflate(block); 140 inflate(block);
141 } 141 }
142 142
143 void FastTextAutosizer::inflateListItem(RenderListItem* listItem, RenderListMark er* listItemMarker) 143 void FastTextAutosizer::inflateListItem(RenderListItem* listItem, RenderListMark er* listItemMarker)
144 { 144 {
145 if (!enabled()) 145 if (!enabled() || m_pageAutosizingStatus != PageNeedsAutosizing)
146 return; 146 return;
147 ASSERT(listItem && listItemMarker); 147 ASSERT(listItem && listItemMarker);
148 #ifndef NDEBUG 148 #ifndef NDEBUG
149 m_blocksThatHaveBegunLayout.add(listItem); 149 m_blocksThatHaveBegunLayout.add(listItem);
150 #endif 150 #endif
151 // Force the LI to be inside the DBCAT when computing the multiplier. 151 // 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. 152 // This guarantees that the DBCAT has entered layout, so we can ask for its width.
153 // It also makes sense because the list marker is autosized like a text node . 153 // It also makes sense because the list marker is autosized like a text node .
154 float multiplier = clusterMultiplier(currentCluster()); 154 float multiplier = clusterMultiplier(currentCluster());
155 155
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 } 189 }
190 } 190 }
191 } 191 }
192 } 192 }
193 } 193 }
194 } 194 }
195 } 195 }
196 196
197 void FastTextAutosizer::endLayout(RenderBlock* block) 197 void FastTextAutosizer::endLayout(RenderBlock* block)
198 { 198 {
199 ASSERT(enabled()); 199 ASSERT(enabled() && m_pageAutosizingStatus == PageNeedsAutosizing);
200 200
201 if (block == m_firstBlock) { 201 if (block == m_firstBlock) {
202 m_firstBlock = 0; 202 m_firstBlock = 0;
203 m_pageAutosizingStatus = PageAutosizingStatusUnknown;
203 m_clusterStack.clear(); 204 m_clusterStack.clear();
204 m_superclusters.clear(); 205 m_superclusters.clear();
205 #ifndef NDEBUG 206 #ifndef NDEBUG
206 m_blocksThatHaveBegunLayout.clear(); 207 m_blocksThatHaveBegunLayout.clear();
207 #endif 208 #endif
208 } else if (currentCluster()->m_root == block) { 209 } else if (currentCluster()->m_root == block) {
209 m_clusterStack.removeLast(); 210 m_clusterStack.removeLast();
210 } 211 }
211 } 212 }
212 213
(...skipping 14 matching lines...) Expand all
227 } 228 }
228 229
229 bool FastTextAutosizer::enabled() 230 bool FastTextAutosizer::enabled()
230 { 231 {
231 if (!m_document->settings() || !m_document->page() || m_document->printing() ) 232 if (!m_document->settings() || !m_document->page() || m_document->printing() )
232 return false; 233 return false;
233 234
234 return m_document->settings()->textAutosizingEnabled(); 235 return m_document->settings()->textAutosizingEnabled();
235 } 236 }
236 237
237 void FastTextAutosizer::prepareRenderViewInfo() 238 void FastTextAutosizer::updateRenderViewInfo()
238 { 239 {
239 RenderView* renderView = toRenderView(m_document->renderer()); 240 RenderView* renderView = toRenderView(m_document->renderer());
240 bool horizontalWritingMode = isHorizontalWritingMode(renderView->style()->wr itingMode()); 241 bool horizontalWritingMode = isHorizontalWritingMode(renderView->style()->wr itingMode());
241 242
242 LocalFrame* mainFrame = m_document->page()->mainFrame(); 243 LocalFrame* mainFrame = m_document->page()->mainFrame();
243 IntSize frameSize = m_document->settings()->textAutosizingWindowSizeOverride (); 244 IntSize frameSize = m_document->settings()->textAutosizingWindowSizeOverride ();
244 if (frameSize.isEmpty()) 245 if (frameSize.isEmpty())
245 frameSize = mainFrame->view()->unscaledVisibleContentSize(IncludeScrollb ars); 246 frameSize = mainFrame->view()->unscaledVisibleContentSize(IncludeScrollb ars);
246 m_frameWidth = horizontalWritingMode ? frameSize.width() : frameSize.height( ); 247 m_frameWidth = horizontalWritingMode ? frameSize.width() : frameSize.height( );
247 248
248 IntSize layoutSize = m_document->page()->mainFrame()->view()->layoutSize(); 249 IntSize layoutSize = m_document->page()->mainFrame()->view()->layoutSize();
249 m_layoutWidth = horizontalWritingMode ? layoutSize.width() : layoutSize.heig ht(); 250 m_layoutWidth = horizontalWritingMode ? layoutSize.width() : layoutSize.heig ht();
250 251
251 // Compute the base font scale multiplier based on device and accessibility settings. 252 // Compute the base font scale multiplier based on device and accessibility settings.
252 m_baseMultiplier = m_document->settings()->accessibilityFontScaleFactor(); 253 m_baseMultiplier = m_document->settings()->accessibilityFontScaleFactor();
253 // If the page has a meta viewport or @viewport, don't apply the device scal e adjustment. 254 // If the page has a meta viewport or @viewport, don't apply the device scal e adjustment.
254 const ViewportDescription& viewportDescription = m_document->page()->mainFra me()->document()->viewportDescription(); 255 const ViewportDescription& viewportDescription = m_document->page()->mainFra me()->document()->viewportDescription();
255 if (!viewportDescription.isSpecifiedByAuthor()) { 256 if (!viewportDescription.isSpecifiedByAuthor()) {
256 float deviceScaleAdjustment = m_document->settings()->deviceScaleAdjustm ent(); 257 float deviceScaleAdjustment = m_document->settings()->deviceScaleAdjustm ent();
257 m_baseMultiplier *= deviceScaleAdjustment; 258 m_baseMultiplier *= deviceScaleAdjustment;
258 } 259 }
260
261 m_pageAutosizingStatus = m_frameWidth && (m_baseMultiplier * (static_cast<fl oat>(m_layoutWidth) / m_frameWidth) > 1.0f)
262 ? PageNeedsAutosizing : PageDoesNotNeedAutosizing;
263
259 #ifndef NDEBUG 264 #ifndef NDEBUG
260 m_renderViewInfoPrepared = true; 265 m_renderViewInfoPrepared = true;
261 #endif 266 #endif
262 } 267 }
263 268
264 bool FastTextAutosizer::isFingerprintingCandidate(const RenderBlock* block) 269 bool FastTextAutosizer::isFingerprintingCandidate(const RenderBlock* block)
265 { 270 {
266 // FIXME: move the logic out of TextAutosizer.cpp into this class. 271 // FIXME: move the logic out of TextAutosizer.cpp into this class.
267 return block->isRenderView() 272 return block->isRenderView()
268 || (TextAutosizer::isAutosizingContainer(block) 273 || (TextAutosizer::isAutosizingContainer(block)
269 && (TextAutosizer::isIndependentDescendant(block) 274 && (TextAutosizer::isIndependentDescendant(block)
270 || mightBeWiderOrNarrowerDescendant(block))); 275 || mightBeWiderOrNarrowerDescendant(block)));
271 } 276 }
272 277
273 bool FastTextAutosizer::clusterWouldHaveEnoughTextToAutosize(const RenderBlock* root, const RenderBlock* widthProvider) 278 bool FastTextAutosizer::clusterWouldHaveEnoughTextToAutosize(const RenderBlock* root, const RenderBlock* widthProvider)
274 { 279 {
275 Cluster hypotheticalCluster(root, true, 0); 280 Cluster hypotheticalCluster(root, true, 0);
276 return clusterHasEnoughTextToAutosize(&hypotheticalCluster, widthProvider); 281 return clusterHasEnoughTextToAutosize(&hypotheticalCluster, widthProvider);
277 } 282 }
278 283
279 bool FastTextAutosizer::clusterHasEnoughTextToAutosize(Cluster* cluster, const R enderBlock* widthProvider) 284 bool FastTextAutosizer::clusterHasEnoughTextToAutosize(Cluster* cluster, const R enderBlock* widthProvider)
280 { 285 {
281 if (cluster->m_hasEnoughTextToAutosize != Unknown) 286 if (cluster->m_hasEnoughTextToAutosize != UnknownAmountOfText)
282 return cluster->m_hasEnoughTextToAutosize == Yes; 287 return cluster->m_hasEnoughTextToAutosize == HasEnoughText;
283 288
284 const RenderBlock* root = cluster->m_root; 289 const RenderBlock* root = cluster->m_root;
285 if (!widthProvider) 290 if (!widthProvider)
286 widthProvider = clusterWidthProvider(root); 291 widthProvider = clusterWidthProvider(root);
287 292
288 // TextAreas and user-modifiable areas get a free pass to autosize regardles s of text content. 293 // TextAreas and user-modifiable areas get a free pass to autosize regardles s of text content.
289 if (root->isTextArea() || (root->style() && root->style()->userModify() != R EAD_ONLY)) { 294 if (root->isTextArea() || (root->style() && root->style()->userModify() != R EAD_ONLY)) {
290 cluster->m_hasEnoughTextToAutosize = Yes; 295 cluster->m_hasEnoughTextToAutosize = HasEnoughText;
291 return true; 296 return true;
292 } 297 }
293 298
294 if (!TextAutosizer::containerShouldBeAutosized(root)) { 299 if (!TextAutosizer::containerShouldBeAutosized(root)) {
295 cluster->m_hasEnoughTextToAutosize = No; 300 cluster->m_hasEnoughTextToAutosize = NotEnoughText;
296 return false; 301 return false;
297 } 302 }
298 303
299 // 4 lines of text is considered enough to autosize. 304 // 4 lines of text is considered enough to autosize.
300 float minimumTextLengthToAutosize = widthFromBlock(widthProvider) * 4; 305 float minimumTextLengthToAutosize = widthFromBlock(widthProvider) * 4;
301 306
302 float length = 0; 307 float length = 0;
303 RenderObject* descendant = root->nextInPreOrder(root); 308 RenderObject* descendant = root->nextInPreOrder(root);
304 while (descendant) { 309 while (descendant) {
305 if (descendant->isRenderBlock()) { 310 if (descendant->isRenderBlock()) {
306 RenderBlock* block = toRenderBlock(descendant); 311 RenderBlock* block = toRenderBlock(descendant);
307 if (TextAutosizer::isAutosizingContainer(block)) { 312 if (TextAutosizer::isAutosizingContainer(block)) {
308 // Note: Ideally we would check isWiderOrNarrowerDescendant here but we only know that 313 // Note: Ideally we would check isWiderOrNarrowerDescendant here but we only know that
309 // after the block has entered layout, which may not be th e case. 314 // after the block has entered layout, which may not be th e case.
310 bool isAutosizingClusterRoot = TextAutosizer::isIndependentDesce ndant(block); 315 bool isAutosizingClusterRoot = TextAutosizer::isIndependentDesce ndant(block);
311 if (isAutosizingClusterRoot || !TextAutosizer::containerShouldBe Autosized(block)) { 316 if (isAutosizingClusterRoot || !TextAutosizer::containerShouldBe Autosized(block)) {
312 descendant = descendant->nextInPreOrderAfterChildren(root); 317 descendant = descendant->nextInPreOrderAfterChildren(root);
313 continue; 318 continue;
314 } 319 }
315 } 320 }
316 } else if (descendant->isText()) { 321 } else if (descendant->isText()) {
317 // Note: Using text().stripWhiteSpace().length() instead of rendered TextLength() because 322 // Note: Using text().stripWhiteSpace().length() instead of rendered TextLength() because
318 // the lineboxes will not be built until layout. These values can be different. 323 // the lineboxes will not be built until layout. These values can be different.
319 // Note: This is an approximation assuming each character is 1em wid e. 324 // Note: This is an approximation assuming each character is 1em wid e.
320 length += toRenderText(descendant)->text().stripWhiteSpace().length( ) * descendant->style()->specifiedFontSize(); 325 length += toRenderText(descendant)->text().stripWhiteSpace().length( ) * descendant->style()->specifiedFontSize();
321 326
322 if (length >= minimumTextLengthToAutosize) { 327 if (length >= minimumTextLengthToAutosize) {
323 cluster->m_hasEnoughTextToAutosize = Yes; 328 cluster->m_hasEnoughTextToAutosize = HasEnoughText;
324 return true; 329 return true;
325 } 330 }
326 } 331 }
327 descendant = descendant->nextInPreOrder(root); 332 descendant = descendant->nextInPreOrder(root);
328 } 333 }
329 334
330 cluster->m_hasEnoughTextToAutosize = No; 335 cluster->m_hasEnoughTextToAutosize = NotEnoughText;
331 return false; 336 return false;
332 } 337 }
333 338
334 FastTextAutosizer::Fingerprint FastTextAutosizer::getFingerprint(const RenderObj ect* renderer) 339 FastTextAutosizer::Fingerprint FastTextAutosizer::getFingerprint(const RenderObj ect* renderer)
335 { 340 {
336 Fingerprint result = m_fingerprintMapper.get(renderer); 341 Fingerprint result = m_fingerprintMapper.get(renderer);
337 if (!result) { 342 if (!result) {
338 result = computeFingerprint(renderer); 343 result = computeFingerprint(renderer);
339 m_fingerprintMapper.add(renderer, result); 344 m_fingerprintMapper.add(renderer, result);
340 } 345 }
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 515
511 float FastTextAutosizer::multiplierFromBlock(const RenderBlock* block) 516 float FastTextAutosizer::multiplierFromBlock(const RenderBlock* block)
512 { 517 {
513 // If block->needsLayout() is false, it does not need to be in m_blocksThatH aveBegunLayout. 518 // If block->needsLayout() is false, it does not need to be in m_blocksThatH aveBegunLayout.
514 // This can happen during layout of a positioned object if the cluster's DBC AT is deeper 519 // This can happen during layout of a positioned object if the cluster's DBC AT is deeper
515 // than the positioned object's containing block, and wasn't marked as needi ng layout. 520 // than the positioned object's containing block, and wasn't marked as needi ng layout.
516 ASSERT(m_blocksThatHaveBegunLayout.contains(block) || !block->needsLayout()) ; 521 ASSERT(m_blocksThatHaveBegunLayout.contains(block) || !block->needsLayout()) ;
517 522
518 // Block width, in CSS pixels. 523 // Block width, in CSS pixels.
519 float blockWidth = widthFromBlock(block); 524 float blockWidth = widthFromBlock(block);
520 float multiplier = min(blockWidth, static_cast<float>(m_layoutWidth)) / m_fr ameWidth; 525 float multiplier = m_frameWidth ? min(blockWidth, static_cast<float>(m_layou tWidth)) / m_frameWidth : 1.0f;
521 526
522 return max(m_baseMultiplier * multiplier, 1.0f); 527 return max(m_baseMultiplier * multiplier, 1.0f);
523 } 528 }
524 529
525 const RenderBlock* FastTextAutosizer::deepestBlockContainingAllText(Cluster* clu ster) 530 const RenderBlock* FastTextAutosizer::deepestBlockContainingAllText(Cluster* clu ster)
526 { 531 {
527 if (!cluster->m_deepestBlockContainingAllText) 532 if (!cluster->m_deepestBlockContainingAllText)
528 cluster->m_deepestBlockContainingAllText = deepestBlockContainingAllText (cluster->m_root); 533 cluster->m_deepestBlockContainingAllText = deepestBlockContainingAllText (cluster->m_root);
529 534
530 return cluster->m_deepestBlockContainingAllText; 535 return cluster->m_deepestBlockContainingAllText;
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 return *m_blocksForFingerprint.get(fingerprint); 700 return *m_blocksForFingerprint.get(fingerprint);
696 } 701 }
697 702
698 RenderObject* FastTextAutosizer::nextChildSkippingChildrenOfBlocks(const RenderO bject* current, const RenderObject* stayWithin) 703 RenderObject* FastTextAutosizer::nextChildSkippingChildrenOfBlocks(const RenderO bject* current, const RenderObject* stayWithin)
699 { 704 {
700 if (current == stayWithin || !current->isRenderBlock()) 705 if (current == stayWithin || !current->isRenderBlock())
701 return current->nextInPreOrder(stayWithin); 706 return current->nextInPreOrder(stayWithin);
702 return current->nextInPreOrderAfterChildren(stayWithin); 707 return current->nextInPreOrderAfterChildren(stayWithin);
703 } 708 }
704 709
710 FastTextAutosizer::LayoutScope::LayoutScope(RenderBlock* block)
711 : m_textAutosizer(block->document().fastTextAutosizer())
712 , m_block(block)
713 {
714 if (!m_textAutosizer)
715 return;
716
717 if (!m_textAutosizer->enabled()) {
718 m_textAutosizer = 0;
719 return;
720 }
721
722 if (m_textAutosizer->m_pageAutosizingStatus == PageAutosizingStatusUnknown)
723 m_textAutosizer->updateRenderViewInfo();
724
725 if (m_textAutosizer->m_pageAutosizingStatus == PageNeedsAutosizing)
726 m_textAutosizer->beginLayout(m_block);
727 else
728 m_textAutosizer = 0;
729 }
730
731 FastTextAutosizer::LayoutScope::~LayoutScope()
732 {
733 if (m_textAutosizer)
734 m_textAutosizer->endLayout(m_block);
735 }
736
705 } // namespace WebCore 737 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/core/rendering/FastTextAutosizer.h ('k') | Source/core/rendering/RenderBlock.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698