OLD | NEW |
---|---|
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 Loading... | |
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) | |
239 , m_updatePageInfoDeferred(false) | |
238 , m_firstBlock(0) | 240 , m_firstBlock(0) |
239 #ifndef NDEBUG | 241 #ifndef NDEBUG |
240 , m_renderViewInfoPrepared(false) | |
241 , m_blocksThatHaveBegunLayout() | 242 , m_blocksThatHaveBegunLayout() |
242 #endif | 243 #endif |
243 , m_superclusters() | 244 , m_superclusters() |
244 , m_clusterStack() | 245 , m_clusterStack() |
245 , m_fingerprintMapper() | 246 , m_fingerprintMapper() |
246 { | 247 { |
247 } | 248 } |
248 | 249 |
249 void FastTextAutosizer::record(const RenderBlock* block) | 250 void FastTextAutosizer::record(const RenderBlock* block) |
250 { | 251 { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
283 #ifndef NDEBUG | 284 #ifndef NDEBUG |
284 m_blocksThatHaveBegunLayout.add(block); | 285 m_blocksThatHaveBegunLayout.add(block); |
285 #endif | 286 #endif |
286 if (Cluster* cluster = maybeCreateCluster(block)) | 287 if (Cluster* cluster = maybeCreateCluster(block)) |
287 m_clusterStack.append(adoptPtr(cluster)); | 288 m_clusterStack.append(adoptPtr(cluster)); |
288 } | 289 } |
289 } | 290 } |
290 | 291 |
291 void FastTextAutosizer::beginLayout(RenderBlock* block) | 292 void FastTextAutosizer::beginLayout(RenderBlock* block) |
292 { | 293 { |
293 ASSERT(enabled() && m_pageAutosizingStatus == PageNeedsAutosizing); | 294 ASSERT(enabled() && m_pageNeedsAutosizing); |
294 #ifndef NDEBUG | 295 #ifndef NDEBUG |
295 m_blocksThatHaveBegunLayout.add(block); | 296 m_blocksThatHaveBegunLayout.add(block); |
296 #endif | 297 #endif |
297 | 298 |
298 if (!m_firstBlock) { | 299 if (!m_firstBlock) { |
299 m_firstBlock = block; | 300 m_firstBlock = block; |
300 prepareClusterStack(block->parent()); | 301 prepareClusterStack(block->parent()); |
301 } else if (block == currentCluster()->m_root) { | 302 } else if (block == currentCluster()->m_root) { |
302 // Ignore beginLayout on the same block twice. | 303 // Ignore beginLayout on the same block twice. |
303 // This can happen with paginated overflow. | 304 // This can happen with paginated overflow. |
304 return; | 305 return; |
305 } | 306 } |
306 | 307 |
307 if (Cluster* cluster = maybeCreateCluster(block)) { | 308 if (Cluster* cluster = maybeCreateCluster(block)) { |
308 m_clusterStack.append(adoptPtr(cluster)); | 309 m_clusterStack.append(adoptPtr(cluster)); |
309 if (block->isTable()) | 310 if (block->isTable()) |
310 inflateTable(toRenderTable(block)); | 311 inflateTable(toRenderTable(block)); |
311 } | 312 } |
312 | 313 |
313 if (block->childrenInline() && block->firstChild()) | 314 if (block->childrenInline() && block->firstChild()) |
314 inflate(block); | 315 inflate(block); |
315 } | 316 } |
316 | 317 |
317 void FastTextAutosizer::inflateListItem(RenderListItem* listItem, RenderListMark er* listItemMarker) | 318 void FastTextAutosizer::inflateListItem(RenderListItem* listItem, RenderListMark er* listItemMarker) |
318 { | 319 { |
319 if (!enabled() || m_pageAutosizingStatus != PageNeedsAutosizing) | 320 if (!enabled() || !m_pageNeedsAutosizing) |
320 return; | 321 return; |
321 ASSERT(listItem && listItemMarker); | 322 ASSERT(listItem && listItemMarker); |
322 #ifndef NDEBUG | 323 #ifndef NDEBUG |
323 m_blocksThatHaveBegunLayout.add(listItem); | 324 m_blocksThatHaveBegunLayout.add(listItem); |
324 #endif | 325 #endif |
325 // Force the LI to be inside the DBCAT when computing the multiplier. | 326 // 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. | 327 // 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 . | 328 // It also makes sense because the list marker is autosized like a text node . |
328 float multiplier = clusterMultiplier(currentCluster()); | 329 float multiplier = clusterMultiplier(currentCluster()); |
329 | 330 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
372 } | 373 } |
373 } | 374 } |
374 } | 375 } |
375 } | 376 } |
376 } | 377 } |
377 } | 378 } |
378 } | 379 } |
379 | 380 |
380 void FastTextAutosizer::endLayout(RenderBlock* block) | 381 void FastTextAutosizer::endLayout(RenderBlock* block) |
381 { | 382 { |
382 ASSERT(enabled() && m_pageAutosizingStatus == PageNeedsAutosizing); | 383 ASSERT(enabled() && m_pageNeedsAutosizing); |
383 | 384 |
384 if (block == m_firstBlock) { | 385 if (block == m_firstBlock) { |
385 m_firstBlock = 0; | 386 m_firstBlock = 0; |
386 m_pageAutosizingStatus = PageAutosizingStatusUnknown; | |
387 m_clusterStack.clear(); | 387 m_clusterStack.clear(); |
388 m_superclusters.clear(); | 388 m_superclusters.clear(); |
389 #ifndef NDEBUG | 389 #ifndef NDEBUG |
390 m_blocksThatHaveBegunLayout.clear(); | 390 m_blocksThatHaveBegunLayout.clear(); |
391 #endif | 391 #endif |
392 } else if (currentCluster()->m_root == block) { | 392 } else if (currentCluster()->m_root == block) { |
393 m_clusterStack.removeLast(); | 393 m_clusterStack.removeLast(); |
394 } | 394 } |
395 } | 395 } |
396 | 396 |
(...skipping 21 matching lines...) Expand all Loading... | |
418 } | 418 } |
419 | 419 |
420 bool FastTextAutosizer::enabled() | 420 bool FastTextAutosizer::enabled() |
421 { | 421 { |
422 if (!m_document->settings() || !m_document->page() || m_document->printing() ) | 422 if (!m_document->settings() || !m_document->page() || m_document->printing() ) |
423 return false; | 423 return false; |
424 | 424 |
425 return m_document->settings()->textAutosizingEnabled(); | 425 return m_document->settings()->textAutosizingEnabled(); |
426 } | 426 } |
427 | 427 |
428 void FastTextAutosizer::updateRenderViewInfo() | 428 void FastTextAutosizer::updatePageInfoInAllFrames() |
429 { | 429 { |
430 if (!enabled()) | |
431 return; | |
432 | |
433 ASSERT(m_document->frame()->isMainFrame()); | |
434 | |
435 for (LocalFrame* frame = m_document->frame(); frame; frame = frame->tree().t raverseNext()) { | |
436 if (FastTextAutosizer* textAutosizer = frame->document()->fastTextAutosi zer()) | |
437 textAutosizer->updatePageInfo(); | |
438 } | |
439 } | |
440 | |
441 void FastTextAutosizer::updatePageInfo() | |
442 { | |
443 if (!enabled() || m_updatePageInfoDeferred) | |
444 return; | |
445 | |
446 int previousFrameWidth = m_frameWidth; | |
447 int previousLayoutWidth = m_layoutWidth; | |
448 float previousBaseMultiplier = m_baseMultiplier; | |
449 | |
430 RenderView* renderView = toRenderView(m_document->renderer()); | 450 RenderView* renderView = toRenderView(m_document->renderer()); |
431 bool horizontalWritingMode = isHorizontalWritingMode(renderView->style()->wr itingMode()); | 451 bool horizontalWritingMode = isHorizontalWritingMode(renderView->style()->wr itingMode()); |
432 | 452 |
433 LocalFrame* mainFrame = m_document->page()->mainFrame(); | 453 LocalFrame* mainFrame = m_document->page()->mainFrame(); |
434 IntSize frameSize = m_document->settings()->textAutosizingWindowSizeOverride (); | 454 IntSize frameSize = m_document->settings()->textAutosizingWindowSizeOverride (); |
435 if (frameSize.isEmpty()) | 455 if (frameSize.isEmpty()) |
436 frameSize = mainFrame->view()->unscaledVisibleContentSize(IncludeScrollb ars); | 456 frameSize = mainFrame->view()->unscaledVisibleContentSize(IncludeScrollb ars); |
437 m_frameWidth = horizontalWritingMode ? frameSize.width() : frameSize.height( ); | 457 m_frameWidth = horizontalWritingMode ? frameSize.width() : frameSize.height( ); |
438 | 458 |
439 IntSize layoutSize = m_document->page()->mainFrame()->view()->layoutSize(); | 459 IntSize layoutSize = m_document->page()->mainFrame()->view()->layoutSize(); |
440 m_layoutWidth = horizontalWritingMode ? layoutSize.width() : layoutSize.heig ht(); | 460 m_layoutWidth = horizontalWritingMode ? layoutSize.width() : layoutSize.heig ht(); |
441 | 461 |
442 // Compute the base font scale multiplier based on device and accessibility settings. | 462 // Compute the base font scale multiplier based on device and accessibility settings. |
443 m_baseMultiplier = m_document->settings()->accessibilityFontScaleFactor(); | 463 m_baseMultiplier = m_document->settings()->accessibilityFontScaleFactor(); |
444 // If the page has a meta viewport or @viewport, don't apply the device scal e adjustment. | 464 // 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(); | 465 const ViewportDescription& viewportDescription = m_document->page()->mainFra me()->document()->viewportDescription(); |
446 if (!viewportDescription.isSpecifiedByAuthor()) { | 466 if (!viewportDescription.isSpecifiedByAuthor()) { |
447 float deviceScaleAdjustment = m_document->settings()->deviceScaleAdjustm ent(); | 467 float deviceScaleAdjustment = m_document->settings()->deviceScaleAdjustm ent(); |
448 m_baseMultiplier *= deviceScaleAdjustment; | 468 m_baseMultiplier *= deviceScaleAdjustment; |
449 } | 469 } |
450 | 470 |
451 m_pageAutosizingStatus = m_frameWidth && (m_baseMultiplier * (static_cast<fl oat>(m_layoutWidth) / m_frameWidth) > 1.0f) | 471 m_pageNeedsAutosizing = !!m_frameWidth |
452 ? PageNeedsAutosizing : PageDoesNotNeedAutosizing; | 472 && (m_baseMultiplier * (static_cast<float>(m_layoutWidth) / m_frameWidth ) > 1.0f); |
453 | 473 |
454 #ifndef NDEBUG | 474 if (!m_pageNeedsAutosizing && m_previouslyAutosized) |
455 m_renderViewInfoPrepared = true; | 475 resetMultipliers(); |
456 #endif | 476 |
477 if (m_pageNeedsAutosizing | |
478 && (m_frameWidth != previousFrameWidth | |
479 || m_layoutWidth != previousLayoutWidth | |
480 || m_baseMultiplier != previousBaseMultiplier)) | |
481 invalidateMultipliers(); | |
482 } | |
483 | |
484 void FastTextAutosizer::resetMultipliers() | |
485 { | |
486 RenderObject* renderer = m_document->renderer(); | |
487 while (renderer) { | |
488 if (RenderStyle* style = renderer->style()) { | |
489 if (style->textAutosizingMultiplier() != 1) | |
490 applyMultiplier(renderer, 1); | |
pdr.
2014/03/24 01:03:18
Do we need to setNeedsLayout here? Normally, apply
skobes
2014/03/25 01:23:24
You're right, applyMultiplier assumes it is inside
| |
491 } | |
492 renderer = renderer->nextInPreOrder(); | |
493 } | |
494 m_previouslyAutosized = false; | |
495 } | |
496 | |
497 void FastTextAutosizer::invalidateMultipliers() | |
timvolodine
2014/03/24 15:24:27
nit: the name seems a bit confusing, it is not dir
skobes
2014/03/25 01:23:24
Done.
| |
498 { | |
499 RenderObject* renderer = m_document->renderer(); | |
500 while (renderer) { | |
501 if (renderer->isText()) { | |
502 renderer->setNeedsLayout(); | |
503 renderer->parent()->setNeedsLayout(); | |
pdr.
2014/03/24 01:03:18
setNeedsLayout already walks up the parent chain s
skobes
2014/03/25 01:23:24
Done. (This was an unsuccessful initial attempt to
| |
504 } | |
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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
619 if (ancestors.count(block) == blocks.size()) | 669 if (ancestors.count(block) == blocks.size()) |
620 return block; | 670 return block; |
621 } | 671 } |
622 } | 672 } |
623 ASSERT_NOT_REACHED(); | 673 ASSERT_NOT_REACHED(); |
624 return 0; | 674 return 0; |
625 } | 675 } |
626 | 676 |
627 float FastTextAutosizer::clusterMultiplier(Cluster* cluster) | 677 float FastTextAutosizer::clusterMultiplier(Cluster* cluster) |
628 { | 678 { |
629 ASSERT(m_renderViewInfoPrepared); | |
630 if (!cluster->m_multiplier) { | 679 if (!cluster->m_multiplier) { |
631 if (cluster->m_root->isTable() | 680 if (cluster->m_root->isTable() |
632 || isIndependentDescendant(cluster->m_root) | 681 || isIndependentDescendant(cluster->m_root) |
633 || isWiderOrNarrowerDescendant(cluster)) { | 682 || isWiderOrNarrowerDescendant(cluster)) { |
634 | 683 |
635 if (cluster->m_supercluster) { | 684 if (cluster->m_supercluster) { |
636 cluster->m_multiplier = superclusterMultiplier(cluster); | 685 cluster->m_multiplier = superclusterMultiplier(cluster); |
637 } else if (clusterHasEnoughTextToAutosize(cluster)) { | 686 } else if (clusterHasEnoughTextToAutosize(cluster)) { |
638 cluster->m_multiplier = multiplierFromBlock(clusterWidthProvider (cluster->m_root)); | 687 cluster->m_multiplier = multiplierFromBlock(clusterWidthProvider (cluster->m_root)); |
639 // Do not inflate table descendants above the table's multiplier . See inflateTable(...) for details. | 688 // Do not inflate table descendants above the table's multiplier . See inflateTable(...) for details. |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
800 ASSERT(renderer); | 849 ASSERT(renderer); |
801 RenderStyle* currentStyle = renderer->style(); | 850 RenderStyle* currentStyle = renderer->style(); |
802 if (currentStyle->textAutosizingMultiplier() == multiplier) | 851 if (currentStyle->textAutosizingMultiplier() == multiplier) |
803 return; | 852 return; |
804 | 853 |
805 // We need to clone the render style to avoid breaking style sharing. | 854 // We need to clone the render style to avoid breaking style sharing. |
806 RefPtr<RenderStyle> style = RenderStyle::clone(currentStyle); | 855 RefPtr<RenderStyle> style = RenderStyle::clone(currentStyle); |
807 style->setTextAutosizingMultiplier(multiplier); | 856 style->setTextAutosizingMultiplier(multiplier); |
808 style->setUnique(); | 857 style->setUnique(); |
809 renderer->setStyleInternal(style.release()); | 858 renderer->setStyleInternal(style.release()); |
859 | |
860 if (multiplier != 1) | |
861 m_previouslyAutosized = true; | |
810 } | 862 } |
811 | 863 |
812 bool FastTextAutosizer::isWiderOrNarrowerDescendant(Cluster* cluster) | 864 bool FastTextAutosizer::isWiderOrNarrowerDescendant(Cluster* cluster) |
813 { | 865 { |
814 if (!cluster->m_parent || !mightBeWiderOrNarrowerDescendant(cluster->m_root) ) | 866 if (!cluster->m_parent || !mightBeWiderOrNarrowerDescendant(cluster->m_root) ) |
815 return true; | 867 return true; |
816 | 868 |
817 const RenderBlock* parentDeepestBlockContainingAllText = deepestBlockContain ingAllText(cluster->m_parent); | 869 const RenderBlock* parentDeepestBlockContainingAllText = deepestBlockContain ingAllText(cluster->m_parent); |
818 ASSERT(m_blocksThatHaveBegunLayout.contains(cluster->m_root)); | 870 ASSERT(m_blocksThatHaveBegunLayout.contains(cluster->m_root)); |
819 ASSERT(m_blocksThatHaveBegunLayout.contains(parentDeepestBlockContainingAllT ext)); | 871 ASSERT(m_blocksThatHaveBegunLayout.contains(parentDeepestBlockContainingAllT ext)); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
910 return *m_blocksForFingerprint.get(fingerprint); | 962 return *m_blocksForFingerprint.get(fingerprint); |
911 } | 963 } |
912 | 964 |
913 FastTextAutosizer::LayoutScope::LayoutScope(RenderBlock* block) | 965 FastTextAutosizer::LayoutScope::LayoutScope(RenderBlock* block) |
914 : m_textAutosizer(block->document().fastTextAutosizer()) | 966 : m_textAutosizer(block->document().fastTextAutosizer()) |
915 , m_block(block) | 967 , m_block(block) |
916 { | 968 { |
917 if (!m_textAutosizer) | 969 if (!m_textAutosizer) |
918 return; | 970 return; |
919 | 971 |
920 if (!m_textAutosizer->enabled()) { | 972 if (m_textAutosizer->enabled() && m_textAutosizer->m_pageNeedsAutosizing) |
921 m_textAutosizer = 0; | |
922 return; | |
923 } | |
924 | |
925 if (m_textAutosizer->m_pageAutosizingStatus == PageAutosizingStatusUnknown) | |
926 m_textAutosizer->updateRenderViewInfo(); | |
927 | |
928 if (m_textAutosizer->m_pageAutosizingStatus == PageNeedsAutosizing) | |
929 m_textAutosizer->beginLayout(m_block); | 973 m_textAutosizer->beginLayout(m_block); |
930 else | 974 else |
931 m_textAutosizer = 0; | 975 m_textAutosizer = 0; |
932 } | 976 } |
933 | 977 |
934 FastTextAutosizer::LayoutScope::~LayoutScope() | 978 FastTextAutosizer::LayoutScope::~LayoutScope() |
935 { | 979 { |
936 if (m_textAutosizer) | 980 if (m_textAutosizer) |
937 m_textAutosizer->endLayout(m_block); | 981 m_textAutosizer->endLayout(m_block); |
938 } | 982 } |
939 | 983 |
940 } // namespace WebCore | 984 } // namespace WebCore |
OLD | NEW |