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

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

Issue 215503003: Reland text autosizing changes. (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 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 { 227 {
228 ASSERT(isPotentialClusterRoot(block)); 228 ASSERT(isPotentialClusterRoot(block));
229 return isIndependentDescendant(block) || mightBeWiderOrNarrowerDescendant(bl ock) || block->isTable(); 229 return isIndependentDescendant(block) || mightBeWiderOrNarrowerDescendant(bl ock) || block->isTable();
230 } 230 }
231 231
232 FastTextAutosizer::FastTextAutosizer(const Document* document) 232 FastTextAutosizer::FastTextAutosizer(const Document* document)
233 : m_document(document) 233 : m_document(document)
234 , m_frameWidth(0) 234 , m_frameWidth(0)
235 , m_layoutWidth(0) 235 , m_layoutWidth(0)
236 , m_baseMultiplier(0) 236 , m_baseMultiplier(0)
237 , m_pageAutosizingStatus(PageAutosizingStatusUnknown) 237 , m_pageNeedsAutosizing(false)
238 , m_previouslyAutosized(false)
238 , m_firstBlock(0) 239 , m_firstBlock(0)
239 #ifndef NDEBUG 240 #ifndef NDEBUG
240 , m_renderViewInfoPrepared(false)
241 , m_blocksThatHaveBegunLayout() 241 , m_blocksThatHaveBegunLayout()
242 #endif 242 #endif
243 , m_superclusters() 243 , m_superclusters()
244 , m_clusterStack() 244 , m_clusterStack()
245 , m_fingerprintMapper() 245 , m_fingerprintMapper()
246 { 246 {
247 } 247 }
248 248
249 void FastTextAutosizer::record(const RenderBlock* block) 249 void FastTextAutosizer::record(const RenderBlock* block)
250 { 250 {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 #ifndef NDEBUG 283 #ifndef NDEBUG
284 m_blocksThatHaveBegunLayout.add(block); 284 m_blocksThatHaveBegunLayout.add(block);
285 #endif 285 #endif
286 if (Cluster* cluster = maybeCreateCluster(block)) 286 if (Cluster* cluster = maybeCreateCluster(block))
287 m_clusterStack.append(adoptPtr(cluster)); 287 m_clusterStack.append(adoptPtr(cluster));
288 } 288 }
289 } 289 }
290 290
291 void FastTextAutosizer::beginLayout(RenderBlock* block) 291 void FastTextAutosizer::beginLayout(RenderBlock* block)
292 { 292 {
293 ASSERT(enabled() && m_pageAutosizingStatus == PageNeedsAutosizing); 293 ASSERT(enabled() && m_pageNeedsAutosizing);
294 #ifndef NDEBUG 294 #ifndef NDEBUG
295 m_blocksThatHaveBegunLayout.add(block); 295 m_blocksThatHaveBegunLayout.add(block);
296 #endif 296 #endif
297 297
298 if (!m_firstBlock) { 298 if (!m_firstBlock) {
299 m_firstBlock = block; 299 m_firstBlock = block;
300 prepareClusterStack(block->parent()); 300 prepareClusterStack(block->parent());
301 } else if (block == currentCluster()->m_root) { 301 } else if (block == currentCluster()->m_root) {
302 // Ignore beginLayout on the same block twice. 302 // Ignore beginLayout on the same block twice.
303 // This can happen with paginated overflow. 303 // This can happen with paginated overflow.
304 return; 304 return;
305 } 305 }
306 306
307 if (Cluster* cluster = maybeCreateCluster(block)) { 307 if (Cluster* cluster = maybeCreateCluster(block)) {
308 m_clusterStack.append(adoptPtr(cluster)); 308 m_clusterStack.append(adoptPtr(cluster));
309 if (block->isTable()) 309 if (block->isTable())
310 inflateTable(toRenderTable(block)); 310 inflateTable(toRenderTable(block));
311 } 311 }
312 312
313 if (block->childrenInline() && block->firstChild()) 313 if (block->childrenInline() && block->firstChild())
314 inflate(block); 314 inflate(block);
315 } 315 }
316 316
317 void FastTextAutosizer::inflateListItem(RenderListItem* listItem, RenderListMark er* listItemMarker) 317 void FastTextAutosizer::inflateListItem(RenderListItem* listItem, RenderListMark er* listItemMarker)
318 { 318 {
319 if (!enabled() || m_pageAutosizingStatus != PageNeedsAutosizing) 319 if (!enabled() || !m_pageNeedsAutosizing)
320 return; 320 return;
321 ASSERT(listItem && listItemMarker); 321 ASSERT(listItem && listItemMarker);
322 #ifndef NDEBUG 322 #ifndef NDEBUG
323 m_blocksThatHaveBegunLayout.add(listItem); 323 m_blocksThatHaveBegunLayout.add(listItem);
324 #endif 324 #endif
325 // Force the LI to be inside the DBCAT when computing the multiplier. 325 // Force the LI to be inside the DBCAT when computing the multiplier.
326 // This guarantees that the DBCAT has entered layout, so we can ask for its width. 326 // This guarantees that the DBCAT has entered layout, so we can ask for its width.
327 // It also makes sense because the list marker is autosized like a text node . 327 // It also makes sense because the list marker is autosized like a text node .
328 float multiplier = clusterMultiplier(currentCluster()); 328 float multiplier = clusterMultiplier(currentCluster());
329 329
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 } 372 }
373 } 373 }
374 } 374 }
375 } 375 }
376 } 376 }
377 } 377 }
378 } 378 }
379 379
380 void FastTextAutosizer::endLayout(RenderBlock* block) 380 void FastTextAutosizer::endLayout(RenderBlock* block)
381 { 381 {
382 ASSERT(enabled() && m_pageAutosizingStatus == PageNeedsAutosizing); 382 ASSERT(enabled() && m_pageNeedsAutosizing);
383 383
384 if (block == m_firstBlock) { 384 if (block == m_firstBlock) {
385 m_firstBlock = 0; 385 m_firstBlock = 0;
386 m_pageAutosizingStatus = PageAutosizingStatusUnknown;
387 m_clusterStack.clear(); 386 m_clusterStack.clear();
388 m_superclusters.clear(); 387 m_superclusters.clear();
389 #ifndef NDEBUG 388 #ifndef NDEBUG
390 m_blocksThatHaveBegunLayout.clear(); 389 m_blocksThatHaveBegunLayout.clear();
391 #endif 390 #endif
392 } else if (currentCluster()->m_root == block) { 391 } else if (currentCluster()->m_root == block) {
393 m_clusterStack.removeLast(); 392 m_clusterStack.removeLast();
394 } 393 }
395 } 394 }
396 395
(...skipping 21 matching lines...) Expand all
418 } 417 }
419 418
420 bool FastTextAutosizer::enabled() 419 bool FastTextAutosizer::enabled()
421 { 420 {
422 if (!m_document->settings() || !m_document->page() || m_document->printing() ) 421 if (!m_document->settings() || !m_document->page() || m_document->printing() )
423 return false; 422 return false;
424 423
425 return m_document->settings()->textAutosizingEnabled(); 424 return m_document->settings()->textAutosizingEnabled();
426 } 425 }
427 426
428 void FastTextAutosizer::updateRenderViewInfo() 427 void FastTextAutosizer::updatePageInfoInAllFrames()
429 { 428 {
429 if (!enabled())
430 return;
431
432 ASSERT(m_document->frame()->isMainFrame());
433
434 for (LocalFrame* frame = m_document->frame(); frame; frame = frame->tree().t raverseNext()) {
435 if (FastTextAutosizer* textAutosizer = frame->document()->fastTextAutosi zer())
436 textAutosizer->updatePageInfo();
437 }
438 }
439
440 void FastTextAutosizer::updatePageInfo()
441 {
442 if (!enabled())
443 return;
444
445 int previousFrameWidth = m_frameWidth;
446 int previousLayoutWidth = m_layoutWidth;
447 float previousBaseMultiplier = m_baseMultiplier;
448
430 RenderView* renderView = toRenderView(m_document->renderer()); 449 RenderView* renderView = toRenderView(m_document->renderer());
431 bool horizontalWritingMode = isHorizontalWritingMode(renderView->style()->wr itingMode()); 450 bool horizontalWritingMode = isHorizontalWritingMode(renderView->style()->wr itingMode());
432 451
433 LocalFrame* mainFrame = m_document->page()->mainFrame(); 452 LocalFrame* mainFrame = m_document->page()->mainFrame();
434 IntSize frameSize = m_document->settings()->textAutosizingWindowSizeOverride (); 453 IntSize frameSize = m_document->settings()->textAutosizingWindowSizeOverride ();
435 if (frameSize.isEmpty()) 454 if (frameSize.isEmpty())
436 frameSize = mainFrame->view()->unscaledVisibleContentSize(IncludeScrollb ars); 455 frameSize = mainFrame->view()->unscaledVisibleContentSize(IncludeScrollb ars);
437 m_frameWidth = horizontalWritingMode ? frameSize.width() : frameSize.height( ); 456 m_frameWidth = horizontalWritingMode ? frameSize.width() : frameSize.height( );
438 457
439 IntSize layoutSize = m_document->page()->mainFrame()->view()->layoutSize(); 458 IntSize layoutSize = m_document->page()->mainFrame()->view()->layoutSize();
440 m_layoutWidth = horizontalWritingMode ? layoutSize.width() : layoutSize.heig ht(); 459 m_layoutWidth = horizontalWritingMode ? layoutSize.width() : layoutSize.heig ht();
441 460
442 // Compute the base font scale multiplier based on device and accessibility settings. 461 // Compute the base font scale multiplier based on device and accessibility settings.
443 m_baseMultiplier = m_document->settings()->accessibilityFontScaleFactor(); 462 m_baseMultiplier = m_document->settings()->accessibilityFontScaleFactor();
444 // If the page has a meta viewport or @viewport, don't apply the device scal e adjustment. 463 // If the page has a meta viewport or @viewport, don't apply the device scal e adjustment.
445 const ViewportDescription& viewportDescription = m_document->page()->mainFra me()->document()->viewportDescription(); 464 const ViewportDescription& viewportDescription = m_document->page()->mainFra me()->document()->viewportDescription();
446 if (!viewportDescription.isSpecifiedByAuthor()) { 465 if (!viewportDescription.isSpecifiedByAuthor()) {
447 float deviceScaleAdjustment = m_document->settings()->deviceScaleAdjustm ent(); 466 float deviceScaleAdjustment = m_document->settings()->deviceScaleAdjustm ent();
448 m_baseMultiplier *= deviceScaleAdjustment; 467 m_baseMultiplier *= deviceScaleAdjustment;
449 } 468 }
450 469
451 m_pageAutosizingStatus = m_frameWidth && (m_baseMultiplier * (static_cast<fl oat>(m_layoutWidth) / m_frameWidth) > 1.0f) 470 m_pageNeedsAutosizing = !!m_frameWidth
452 ? PageNeedsAutosizing : PageDoesNotNeedAutosizing; 471 && (m_baseMultiplier * (static_cast<float>(m_layoutWidth) / m_frameWidth ) > 1.0f);
453 472
454 #ifndef NDEBUG 473 // If we are no longer autosizing the page, we won't do anything during the next layout.
455 m_renderViewInfoPrepared = true; 474 // Set all the multipliers back to 1 now.
456 #endif 475 if (!m_pageNeedsAutosizing && m_previouslyAutosized)
476 resetMultipliers();
477
478 // If page info has changed, multipliers may have changed. Force a layout to recompute them.
479 if (m_pageNeedsAutosizing
480 && (m_frameWidth != previousFrameWidth
481 || m_layoutWidth != previousLayoutWidth
482 || m_baseMultiplier != previousBaseMultiplier))
483 setAllTextNeedsLayout();
484 }
485
486 void FastTextAutosizer::resetMultipliers()
487 {
488 RenderObject* renderer = m_document->renderer();
489 while (renderer) {
490 if (RenderStyle* style = renderer->style()) {
491 if (style->textAutosizingMultiplier() != 1)
492 applyMultiplier(renderer, 1, LayoutNeeded);
493 }
494 renderer = renderer->nextInPreOrder();
495 }
496 m_previouslyAutosized = false;
497 }
498
499 void FastTextAutosizer::setAllTextNeedsLayout()
500 {
501 RenderObject* renderer = m_document->renderer();
502 while (renderer) {
503 if (renderer->isText())
504 renderer->setNeedsLayout();
505 renderer = renderer->nextInPreOrder();
506 }
457 } 507 }
458 508
459 bool FastTextAutosizer::clusterWouldHaveEnoughTextToAutosize(const RenderBlock* root, const RenderBlock* widthProvider) 509 bool FastTextAutosizer::clusterWouldHaveEnoughTextToAutosize(const RenderBlock* root, const RenderBlock* widthProvider)
460 { 510 {
461 Cluster hypotheticalCluster(root, true, 0); 511 Cluster hypotheticalCluster(root, true, 0);
462 return clusterHasEnoughTextToAutosize(&hypotheticalCluster, widthProvider); 512 return clusterHasEnoughTextToAutosize(&hypotheticalCluster, widthProvider);
463 } 513 }
464 514
465 bool FastTextAutosizer::clusterHasEnoughTextToAutosize(Cluster* cluster, const R enderBlock* widthProvider) 515 bool FastTextAutosizer::clusterHasEnoughTextToAutosize(Cluster* cluster, const R enderBlock* widthProvider)
466 { 516 {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 if (ancestors.count(block) == blocks.size()) 664 if (ancestors.count(block) == blocks.size())
615 return block; 665 return block;
616 } 666 }
617 } 667 }
618 ASSERT_NOT_REACHED(); 668 ASSERT_NOT_REACHED();
619 return 0; 669 return 0;
620 } 670 }
621 671
622 float FastTextAutosizer::clusterMultiplier(Cluster* cluster) 672 float FastTextAutosizer::clusterMultiplier(Cluster* cluster)
623 { 673 {
624 ASSERT(m_renderViewInfoPrepared);
625 if (!cluster->m_multiplier) { 674 if (!cluster->m_multiplier) {
626 if (cluster->m_root->isTable() 675 if (cluster->m_root->isTable()
627 || isIndependentDescendant(cluster->m_root) 676 || isIndependentDescendant(cluster->m_root)
628 || isWiderOrNarrowerDescendant(cluster)) { 677 || isWiderOrNarrowerDescendant(cluster)) {
629 678
630 if (cluster->m_supercluster) { 679 if (cluster->m_supercluster) {
631 cluster->m_multiplier = superclusterMultiplier(cluster); 680 cluster->m_multiplier = superclusterMultiplier(cluster);
632 } else if (clusterHasEnoughTextToAutosize(cluster)) { 681 } else if (clusterHasEnoughTextToAutosize(cluster)) {
633 cluster->m_multiplier = multiplierFromBlock(clusterWidthProvider (cluster->m_root)); 682 cluster->m_multiplier = multiplierFromBlock(clusterWidthProvider (cluster->m_root));
634 // Do not inflate table descendants above the table's multiplier . See inflateTable(...) for details. 683 // Do not inflate table descendants above the table's multiplier . See inflateTable(...) for details.
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 if (leaf) 832 if (leaf)
784 return leaf; 833 return leaf;
785 } 834 }
786 child = (firstOrLast == First) ? child->nextSibling() : child->previousS ibling(); 835 child = (firstOrLast == First) ? child->nextSibling() : child->previousS ibling();
787 } 836 }
788 --depth; 837 --depth;
789 838
790 return 0; 839 return 0;
791 } 840 }
792 841
793 void FastTextAutosizer::applyMultiplier(RenderObject* renderer, float multiplier ) 842 void FastTextAutosizer::applyMultiplier(RenderObject* renderer, float multiplier , RelayoutBehavior relayoutBehavior)
794 { 843 {
795 ASSERT(renderer); 844 ASSERT(renderer);
796 RenderStyle* currentStyle = renderer->style(); 845 RenderStyle* currentStyle = renderer->style();
797 if (currentStyle->textAutosizingMultiplier() == multiplier) 846 if (currentStyle->textAutosizingMultiplier() == multiplier)
798 return; 847 return;
799 848
800 // We need to clone the render style to avoid breaking style sharing. 849 // We need to clone the render style to avoid breaking style sharing.
801 RefPtr<RenderStyle> style = RenderStyle::clone(currentStyle); 850 RefPtr<RenderStyle> style = RenderStyle::clone(currentStyle);
802 style->setTextAutosizingMultiplier(multiplier); 851 style->setTextAutosizingMultiplier(multiplier);
803 style->setUnique(); 852 style->setUnique();
804 renderer->setStyleInternal(style.release()); 853
854 switch (relayoutBehavior) {
855 case AlreadyInLayout:
856 renderer->setStyleInternal(style.release());
857 if (renderer->isRenderBlock())
858 toRenderBlock(renderer)->invalidateLineHeight();
859 break;
860
861 case LayoutNeeded:
862 renderer->setStyle(style.release());
863 break;
864 }
865
866 if (multiplier != 1)
867 m_previouslyAutosized = true;
805 } 868 }
806 869
807 bool FastTextAutosizer::isWiderOrNarrowerDescendant(Cluster* cluster) 870 bool FastTextAutosizer::isWiderOrNarrowerDescendant(Cluster* cluster)
808 { 871 {
809 if (!cluster->m_parent || !mightBeWiderOrNarrowerDescendant(cluster->m_root) ) 872 if (!cluster->m_parent || !mightBeWiderOrNarrowerDescendant(cluster->m_root) )
810 return true; 873 return true;
811 874
812 const RenderBlock* parentDeepestBlockContainingAllText = deepestBlockContain ingAllText(cluster->m_parent); 875 const RenderBlock* parentDeepestBlockContainingAllText = deepestBlockContain ingAllText(cluster->m_parent);
813 ASSERT(m_blocksThatHaveBegunLayout.contains(cluster->m_root)); 876 ASSERT(m_blocksThatHaveBegunLayout.contains(cluster->m_root));
814 ASSERT(m_blocksThatHaveBegunLayout.contains(parentDeepestBlockContainingAllT ext)); 877 ASSERT(m_blocksThatHaveBegunLayout.contains(parentDeepestBlockContainingAllT ext));
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 return *m_blocksForFingerprint.get(fingerprint); 968 return *m_blocksForFingerprint.get(fingerprint);
906 } 969 }
907 970
908 FastTextAutosizer::LayoutScope::LayoutScope(RenderBlock* block) 971 FastTextAutosizer::LayoutScope::LayoutScope(RenderBlock* block)
909 : m_textAutosizer(block->document().fastTextAutosizer()) 972 : m_textAutosizer(block->document().fastTextAutosizer())
910 , m_block(block) 973 , m_block(block)
911 { 974 {
912 if (!m_textAutosizer) 975 if (!m_textAutosizer)
913 return; 976 return;
914 977
915 if (!m_textAutosizer->enabled()) { 978 if (m_textAutosizer->enabled() && m_textAutosizer->m_pageNeedsAutosizing)
916 m_textAutosizer = 0;
917 return;
918 }
919
920 if (m_textAutosizer->m_pageAutosizingStatus == PageAutosizingStatusUnknown)
921 m_textAutosizer->updateRenderViewInfo();
922
923 if (m_textAutosizer->m_pageAutosizingStatus == PageNeedsAutosizing)
924 m_textAutosizer->beginLayout(m_block); 979 m_textAutosizer->beginLayout(m_block);
925 else 980 else
926 m_textAutosizer = 0; 981 m_textAutosizer = 0;
927 } 982 }
928 983
929 FastTextAutosizer::LayoutScope::~LayoutScope() 984 FastTextAutosizer::LayoutScope::~LayoutScope()
930 { 985 {
931 if (m_textAutosizer) 986 if (m_textAutosizer)
932 m_textAutosizer->endLayout(m_block); 987 m_textAutosizer->endLayout(m_block);
933 } 988 }
934 989
935 } // namespace WebCore 990 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698