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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 } | 147 } |
148 | 148 |
149 static bool isPotentialClusterRoot(const LayoutObject* layoutObject) { | 149 static bool isPotentialClusterRoot(const LayoutObject* layoutObject) { |
150 // "Potential cluster roots" are the smallest unit for which we can | 150 // "Potential cluster roots" are the smallest unit for which we can |
151 // enable/disable text autosizing. | 151 // enable/disable text autosizing. |
152 // - Must have children. | 152 // - Must have children. |
153 // An exception is made for LayoutView which should create a root to | 153 // An exception is made for LayoutView which should create a root to |
154 // maintain consistency with documents that have no child nodes but may | 154 // maintain consistency with documents that have no child nodes but may |
155 // still have LayoutObject children. | 155 // still have LayoutObject children. |
156 // - Must not be inline, as different multipliers on one line looks terrible. | 156 // - Must not be inline, as different multipliers on one line looks terrible. |
157 // Exceptions are inline-block and alike elements (inline-table, -webkit-inl
ine-*), | 157 // Exceptions are inline-block and alike elements (inline-table, |
158 // as they often contain entire multi-line columns of text. | 158 // -webkit-inline-*), as they often contain entire multi-line columns of |
| 159 // text. |
159 // - Must not be normal list items, as items in the same list should look | 160 // - Must not be normal list items, as items in the same list should look |
160 // consistent, unless they are floating or position:absolute/fixed. | 161 // consistent, unless they are floating or position:absolute/fixed. |
161 Node* node = layoutObject->generatingNode(); | 162 Node* node = layoutObject->generatingNode(); |
162 if (node && !node->hasChildren() && !layoutObject->isLayoutView()) | 163 if (node && !node->hasChildren() && !layoutObject->isLayoutView()) |
163 return false; | 164 return false; |
164 if (!layoutObject->isLayoutBlock()) | 165 if (!layoutObject->isLayoutBlock()) |
165 return false; | 166 return false; |
166 if (layoutObject->isInline() && | 167 if (layoutObject->isInline() && |
167 !layoutObject->style()->isDisplayReplacedType()) | 168 !layoutObject->style()->isDisplayReplacedType()) |
168 return false; | 169 return false; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 layoutObject = layoutObject->nextInPreOrderAfterChildren(block); | 221 layoutObject = layoutObject->nextInPreOrderAfterChildren(block); |
221 continue; | 222 continue; |
222 } | 223 } |
223 layoutObject = layoutObject->nextInPreOrder(block); | 224 layoutObject = layoutObject->nextInPreOrder(block); |
224 } | 225 } |
225 | 226 |
226 return (linkCount >= 3); | 227 return (linkCount >= 3); |
227 } | 228 } |
228 | 229 |
229 static bool blockHeightConstrained(const LayoutBlock* block) { | 230 static bool blockHeightConstrained(const LayoutBlock* block) { |
230 // FIXME: Propagate constrainedness down the tree, to avoid inefficiently walk
ing back up from each box. | 231 // FIXME: Propagate constrainedness down the tree, to avoid inefficiently |
| 232 // walking back up from each box. |
231 // FIXME: This code needs to take into account vertical writing modes. | 233 // FIXME: This code needs to take into account vertical writing modes. |
232 // FIXME: Consider additional heuristics, such as ignoring fixed heights if th
e content is already overflowing before autosizing kicks in. | 234 // FIXME: Consider additional heuristics, such as ignoring fixed heights if |
| 235 // the content is already overflowing before autosizing kicks in. |
233 for (; block; block = block->containingBlock()) { | 236 for (; block; block = block->containingBlock()) { |
234 const ComputedStyle& style = block->styleRef(); | 237 const ComputedStyle& style = block->styleRef(); |
235 if (style.overflowY() >= OverflowScroll) | 238 if (style.overflowY() >= OverflowScroll) |
236 return false; | 239 return false; |
237 if (style.height().isSpecified() || style.maxHeight().isSpecified() || | 240 if (style.height().isSpecified() || style.maxHeight().isSpecified() || |
238 block->isOutOfFlowPositioned()) { | 241 block->isOutOfFlowPositioned()) { |
239 // Some sites (e.g. wikipedia) set their html and/or body elements to heig
ht:100%, | 242 // Some sites (e.g. wikipedia) set their html and/or body elements to |
240 // without intending to constrain the height of the content within them. | 243 // height:100%, without intending to constrain the height of the content |
| 244 // within them. |
241 return !block->isDocumentElement() && !block->isBody() && | 245 return !block->isDocumentElement() && !block->isBody() && |
242 !block->isLayoutView(); | 246 !block->isLayoutView(); |
243 } | 247 } |
244 if (block->isFloating()) | 248 if (block->isFloating()) |
245 return false; | 249 return false; |
246 } | 250 } |
247 return false; | 251 return false; |
248 } | 252 } |
249 | 253 |
250 static bool blockOrImmediateChildrenAreFormControls(const LayoutBlock* block) { | 254 static bool blockOrImmediateChildrenAreFormControls(const LayoutBlock* block) { |
(...skipping 22 matching lines...) Expand all Loading... |
273 if (!block->style()->autoWrap()) | 277 if (!block->style()->autoWrap()) |
274 return true; | 278 return true; |
275 | 279 |
276 if (blockHeightConstrained(block)) | 280 if (blockHeightConstrained(block)) |
277 return true; | 281 return true; |
278 | 282 |
279 return false; | 283 return false; |
280 } | 284 } |
281 | 285 |
282 static bool hasExplicitWidth(const LayoutBlock* block) { | 286 static bool hasExplicitWidth(const LayoutBlock* block) { |
283 // FIXME: This heuristic may need to be expanded to other ways a block can be
wider or narrower | 287 // FIXME: This heuristic may need to be expanded to other ways a block can be |
284 // than its parent containing block. | 288 // wider or narrower than its parent containing block. |
285 return block->style() && block->style()->width().isSpecified(); | 289 return block->style() && block->style()->width().isSpecified(); |
286 } | 290 } |
287 | 291 |
288 TextAutosizer::TextAutosizer(const Document* document) | 292 TextAutosizer::TextAutosizer(const Document* document) |
289 : m_document(document), | 293 : m_document(document), |
290 m_firstBlockToBeginLayout(nullptr), | 294 m_firstBlockToBeginLayout(nullptr), |
291 #if ENABLE(ASSERT) | 295 #if ENABLE(ASSERT) |
292 m_blocksThatHaveBegunLayout(), | 296 m_blocksThatHaveBegunLayout(), |
293 #endif | 297 #endif |
294 m_superclusters(), | 298 m_superclusters(), |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 | 390 |
387 void TextAutosizer::inflateAutoTable(LayoutTable* table) { | 391 void TextAutosizer::inflateAutoTable(LayoutTable* table) { |
388 ASSERT(table); | 392 ASSERT(table); |
389 ASSERT(!table->style()->isFixedTableLayout()); | 393 ASSERT(!table->style()->isFixedTableLayout()); |
390 ASSERT(table->containingBlock()); | 394 ASSERT(table->containingBlock()); |
391 | 395 |
392 Cluster* cluster = currentCluster(); | 396 Cluster* cluster = currentCluster(); |
393 if (cluster->m_root != table) | 397 if (cluster->m_root != table) |
394 return; | 398 return; |
395 | 399 |
396 // Pre-inflate cells that have enough text so that their inflated preferred wi
dths will be used | 400 // Pre-inflate cells that have enough text so that their inflated preferred |
397 // for column sizing. | 401 // widths will be used for column sizing. |
398 for (LayoutObject* section = table->firstChild(); section; | 402 for (LayoutObject* section = table->firstChild(); section; |
399 section = section->nextSibling()) { | 403 section = section->nextSibling()) { |
400 if (!section->isTableSection()) | 404 if (!section->isTableSection()) |
401 continue; | 405 continue; |
402 for (LayoutTableRow* row = toLayoutTableSection(section)->firstRow(); row; | 406 for (LayoutTableRow* row = toLayoutTableSection(section)->firstRow(); row; |
403 row = row->nextRow()) { | 407 row = row->nextRow()) { |
404 for (LayoutTableCell* cell = row->firstCell(); cell; | 408 for (LayoutTableCell* cell = row->firstCell(); cell; |
405 cell = cell->nextCell()) { | 409 cell = cell->nextCell()) { |
406 if (!cell->needsLayout()) | 410 if (!cell->needsLayout()) |
407 continue; | 411 continue; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 LayoutObject* child = nullptr; | 446 LayoutObject* child = nullptr; |
443 if (parent->isLayoutBlock() && | 447 if (parent->isLayoutBlock() && |
444 (parent->childrenInline() || behavior == DescendToInnerBlocks)) | 448 (parent->childrenInline() || behavior == DescendToInnerBlocks)) |
445 child = toLayoutBlock(parent)->firstChild(); | 449 child = toLayoutBlock(parent)->firstChild(); |
446 else if (parent->isLayoutInline()) | 450 else if (parent->isLayoutInline()) |
447 child = toLayoutInline(parent)->firstChild(); | 451 child = toLayoutInline(parent)->firstChild(); |
448 | 452 |
449 while (child) { | 453 while (child) { |
450 if (child->isText()) { | 454 if (child->isText()) { |
451 hasTextChild = true; | 455 hasTextChild = true; |
452 // We only calculate this multiplier on-demand to ensure the parent block
of this text | 456 // We only calculate this multiplier on-demand to ensure the parent block |
453 // has entered layout. | 457 // of this text has entered layout. |
454 if (!multiplier) | 458 if (!multiplier) |
455 multiplier = | 459 multiplier = |
456 cluster->m_flags & SUPPRESSING ? 1.0f : clusterMultiplier(cluster); | 460 cluster->m_flags & SUPPRESSING ? 1.0f : clusterMultiplier(cluster); |
457 applyMultiplier(child, multiplier, layouter); | 461 applyMultiplier(child, multiplier, layouter); |
458 | 462 |
459 // FIXME: Investigate why MarkOnlyThis is sufficient. | 463 // FIXME: Investigate why MarkOnlyThis is sufficient. |
460 if (parent->isLayoutInline()) | 464 if (parent->isLayoutInline()) |
461 child->setPreferredLogicalWidthsDirty(MarkOnlyThis); | 465 child->setPreferredLogicalWidthsDirty(MarkOnlyThis); |
462 } else if (child->isLayoutInline()) { | 466 } else if (child->isLayoutInline()) { |
463 multiplier = inflate(child, layouter, behavior, multiplier); | 467 multiplier = inflate(child, layouter, behavior, multiplier); |
464 } else if (child->isLayoutBlock() && behavior == DescendToInnerBlocks && | 468 } else if (child->isLayoutBlock() && behavior == DescendToInnerBlocks && |
465 !classifyBlock(child, | 469 !classifyBlock(child, |
466 INDEPENDENT | EXPLICIT_WIDTH | SUPPRESSING)) { | 470 INDEPENDENT | EXPLICIT_WIDTH | SUPPRESSING)) { |
467 multiplier = inflate(child, layouter, behavior, multiplier); | 471 multiplier = inflate(child, layouter, behavior, multiplier); |
468 } | 472 } |
469 child = child->nextSibling(); | 473 child = child->nextSibling(); |
470 } | 474 } |
471 | 475 |
472 if (hasTextChild) { | 476 if (hasTextChild) { |
473 applyMultiplier(parent, multiplier, | 477 applyMultiplier(parent, multiplier, |
474 layouter); // Parent handles line spacing. | 478 layouter); // Parent handles line spacing. |
475 } else if (!parent->isListItem()) { | 479 } else if (!parent->isListItem()) { |
476 // For consistency, a block with no immediate text child should always have
a | 480 // For consistency, a block with no immediate text child should always have |
477 // multiplier of 1. | 481 // a multiplier of 1. |
478 applyMultiplier(parent, 1, layouter); | 482 applyMultiplier(parent, 1, layouter); |
479 } | 483 } |
480 | 484 |
481 if (parent->isListItem()) { | 485 if (parent->isListItem()) { |
482 float multiplier = clusterMultiplier(cluster); | 486 float multiplier = clusterMultiplier(cluster); |
483 applyMultiplier(parent, multiplier, layouter); | 487 applyMultiplier(parent, multiplier, layouter); |
484 | 488 |
485 // The list item has to be treated special because we can have a tree such t
hat you have | 489 // The list item has to be treated special because we can have a tree such |
486 // a list item for a form inside it. The list marker then ends up inside the
form and when | 490 // that you have a list item for a form inside it. The list marker then ends |
487 // we try to get the clusterMultiplier we have the wrong cluster root to wor
k from and get | 491 // up inside the form and when we try to get the clusterMultiplier we have |
488 // the wrong value. | 492 // the wrong cluster root to work from and get the wrong value. |
489 LayoutListItem* item = toLayoutListItem(parent); | 493 LayoutListItem* item = toLayoutListItem(parent); |
490 if (LayoutListMarker* marker = item->marker()) { | 494 if (LayoutListMarker* marker = item->marker()) { |
491 applyMultiplier(marker, multiplier, layouter); | 495 applyMultiplier(marker, multiplier, layouter); |
492 marker->setPreferredLogicalWidthsDirty(MarkOnlyThis); | 496 marker->setPreferredLogicalWidthsDirty(MarkOnlyThis); |
493 } | 497 } |
494 } | 498 } |
495 | 499 |
496 if (m_pageInfo.m_hasAutosized) | 500 if (m_pageInfo.m_hasAutosized) |
497 UseCounter::count(*m_document, UseCounter::TextAutosizing); | 501 UseCounter::count(*m_document, UseCounter::TextAutosizing); |
498 | 502 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 if (frameSize.isEmpty()) | 556 if (frameSize.isEmpty()) |
553 frameSize = windowSize(); | 557 frameSize = windowSize(); |
554 | 558 |
555 m_pageInfo.m_frameWidth = | 559 m_pageInfo.m_frameWidth = |
556 horizontalWritingMode ? frameSize.width() : frameSize.height(); | 560 horizontalWritingMode ? frameSize.width() : frameSize.height(); |
557 | 561 |
558 IntSize layoutSize = mainFrame->view()->layoutSize(); | 562 IntSize layoutSize = mainFrame->view()->layoutSize(); |
559 m_pageInfo.m_layoutWidth = | 563 m_pageInfo.m_layoutWidth = |
560 horizontalWritingMode ? layoutSize.width() : layoutSize.height(); | 564 horizontalWritingMode ? layoutSize.width() : layoutSize.height(); |
561 | 565 |
562 // TODO(pdr): Accessibility should be moved out of the text autosizer. See:
crbug.com/645717. | 566 // TODO(pdr): Accessibility should be moved out of the text autosizer. See: |
| 567 // crbug.com/645717. |
563 m_pageInfo.m_accessibilityFontScaleFactor = | 568 m_pageInfo.m_accessibilityFontScaleFactor = |
564 m_document->settings()->accessibilityFontScaleFactor(); | 569 m_document->settings()->accessibilityFontScaleFactor(); |
565 | 570 |
566 // If the page has a meta viewport or @viewport, don't apply the device scal
e adjustment. | 571 // If the page has a meta viewport or @viewport, don't apply the device |
| 572 // scale adjustment. |
567 if (!mainFrame->document()->viewportDescription().isSpecifiedByAuthor()) | 573 if (!mainFrame->document()->viewportDescription().isSpecifiedByAuthor()) |
568 m_pageInfo.m_deviceScaleAdjustment = | 574 m_pageInfo.m_deviceScaleAdjustment = |
569 m_document->settings()->deviceScaleAdjustment(); | 575 m_document->settings()->deviceScaleAdjustment(); |
570 else | 576 else |
571 m_pageInfo.m_deviceScaleAdjustment = 1.0f; | 577 m_pageInfo.m_deviceScaleAdjustment = 1.0f; |
572 | 578 |
573 // TODO(pdr): pageNeedsAutosizing should take into account whether text-size
-adjust is used | 579 // TODO(pdr): pageNeedsAutosizing should take into account whether |
574 // anywhere on the page because that also needs to trigger autosizing. See:
crbug.com/646237. | 580 // text-size-adjust is used anywhere on the page because that also needs to |
| 581 // trigger autosizing. See: crbug.com/646237. |
575 m_pageInfo.m_pageNeedsAutosizing = | 582 m_pageInfo.m_pageNeedsAutosizing = |
576 !!m_pageInfo.m_frameWidth && | 583 !!m_pageInfo.m_frameWidth && |
577 (m_pageInfo.m_accessibilityFontScaleFactor * | 584 (m_pageInfo.m_accessibilityFontScaleFactor * |
578 m_pageInfo.m_deviceScaleAdjustment * | 585 m_pageInfo.m_deviceScaleAdjustment * |
579 (static_cast<float>(m_pageInfo.m_layoutWidth) / | 586 (static_cast<float>(m_pageInfo.m_layoutWidth) / |
580 m_pageInfo.m_frameWidth) > | 587 m_pageInfo.m_frameWidth) > |
581 1.0f); | 588 1.0f); |
582 } | 589 } |
583 | 590 |
584 if (m_pageInfo.m_pageNeedsAutosizing) { | 591 if (m_pageInfo.m_pageNeedsAutosizing) { |
585 // If page info has changed, multipliers may have changed. Force a layout to
recompute them. | 592 // If page info has changed, multipliers may have changed. Force a layout to |
| 593 // recompute them. |
586 if (m_pageInfo.m_frameWidth != previousPageInfo.m_frameWidth || | 594 if (m_pageInfo.m_frameWidth != previousPageInfo.m_frameWidth || |
587 m_pageInfo.m_layoutWidth != previousPageInfo.m_layoutWidth || | 595 m_pageInfo.m_layoutWidth != previousPageInfo.m_layoutWidth || |
588 m_pageInfo.m_accessibilityFontScaleFactor != | 596 m_pageInfo.m_accessibilityFontScaleFactor != |
589 previousPageInfo.m_accessibilityFontScaleFactor || | 597 previousPageInfo.m_accessibilityFontScaleFactor || |
590 m_pageInfo.m_deviceScaleAdjustment != | 598 m_pageInfo.m_deviceScaleAdjustment != |
591 previousPageInfo.m_deviceScaleAdjustment || | 599 previousPageInfo.m_deviceScaleAdjustment || |
592 m_pageInfo.m_settingEnabled != previousPageInfo.m_settingEnabled) | 600 m_pageInfo.m_settingEnabled != previousPageInfo.m_settingEnabled) |
593 setAllTextNeedsLayout(); | 601 setAllTextNeedsLayout(); |
594 } else if (previousPageInfo.m_hasAutosized) { | 602 } else if (previousPageInfo.m_hasAutosized) { |
595 // If we are no longer autosizing the page, we won't do anything during the
next layout. | 603 // If we are no longer autosizing the page, we won't do anything during the |
596 // Set all the multipliers back to 1 now. | 604 // next layout. Set all the multipliers back to 1 now. |
597 resetMultipliers(); | 605 resetMultipliers(); |
598 m_pageInfo.m_hasAutosized = false; | 606 m_pageInfo.m_hasAutosized = false; |
599 } | 607 } |
600 } | 608 } |
601 | 609 |
602 IntSize TextAutosizer::windowSize() const { | 610 IntSize TextAutosizer::windowSize() const { |
603 Page* page = m_document->page(); | 611 Page* page = m_document->page(); |
604 ASSERT(page); | 612 ASSERT(page); |
605 return page->frameHost().visualViewport().size(); | 613 return page->frameHost().visualViewport().size(); |
606 } | 614 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 bool TextAutosizer::clusterHasEnoughTextToAutosize( | 671 bool TextAutosizer::clusterHasEnoughTextToAutosize( |
664 Cluster* cluster, | 672 Cluster* cluster, |
665 const LayoutBlock* widthProvider) { | 673 const LayoutBlock* widthProvider) { |
666 if (cluster->m_hasEnoughTextToAutosize != UnknownAmountOfText) | 674 if (cluster->m_hasEnoughTextToAutosize != UnknownAmountOfText) |
667 return cluster->m_hasEnoughTextToAutosize == HasEnoughText; | 675 return cluster->m_hasEnoughTextToAutosize == HasEnoughText; |
668 | 676 |
669 const LayoutBlock* root = cluster->m_root; | 677 const LayoutBlock* root = cluster->m_root; |
670 if (!widthProvider) | 678 if (!widthProvider) |
671 widthProvider = clusterWidthProvider(root); | 679 widthProvider = clusterWidthProvider(root); |
672 | 680 |
673 // TextAreas and user-modifiable areas get a free pass to autosize regardless
of text content. | 681 // TextAreas and user-modifiable areas get a free pass to autosize regardless |
| 682 // of text content. |
674 if (root->isTextArea() || | 683 if (root->isTextArea() || |
675 (root->style() && root->style()->userModify() != READ_ONLY)) { | 684 (root->style() && root->style()->userModify() != READ_ONLY)) { |
676 cluster->m_hasEnoughTextToAutosize = HasEnoughText; | 685 cluster->m_hasEnoughTextToAutosize = HasEnoughText; |
677 return true; | 686 return true; |
678 } | 687 } |
679 | 688 |
680 if (cluster->m_flags & SUPPRESSING) { | 689 if (cluster->m_flags & SUPPRESSING) { |
681 cluster->m_hasEnoughTextToAutosize = NotEnoughText; | 690 cluster->m_hasEnoughTextToAutosize = NotEnoughText; |
682 return false; | 691 return false; |
683 } | 692 } |
684 | 693 |
685 // 4 lines of text is considered enough to autosize. | 694 // 4 lines of text is considered enough to autosize. |
686 float minimumTextLengthToAutosize = widthFromBlock(widthProvider) * 4; | 695 float minimumTextLengthToAutosize = widthFromBlock(widthProvider) * 4; |
687 | 696 |
688 float length = 0; | 697 float length = 0; |
689 LayoutObject* descendant = root->firstChild(); | 698 LayoutObject* descendant = root->firstChild(); |
690 while (descendant) { | 699 while (descendant) { |
691 if (descendant->isLayoutBlock()) { | 700 if (descendant->isLayoutBlock()) { |
692 if (classifyBlock(descendant, INDEPENDENT | SUPPRESSING)) { | 701 if (classifyBlock(descendant, INDEPENDENT | SUPPRESSING)) { |
693 descendant = descendant->nextInPreOrderAfterChildren(root); | 702 descendant = descendant->nextInPreOrderAfterChildren(root); |
694 continue; | 703 continue; |
695 } | 704 } |
696 } else if (descendant->isText()) { | 705 } else if (descendant->isText()) { |
697 // Note: Using text().stripWhiteSpace().length() instead of resolvedTextLe
ngth() because | 706 // Note: Using text().stripWhiteSpace().length() instead of |
698 // the lineboxes will not be built until layout. These values can be diffe
rent. | 707 // resolvedTextLength() because the lineboxes will not be built until |
| 708 // layout. These values can be different. |
699 // Note: This is an approximation assuming each character is 1em wide. | 709 // Note: This is an approximation assuming each character is 1em wide. |
700 length += toLayoutText(descendant)->text().stripWhiteSpace().length() * | 710 length += toLayoutText(descendant)->text().stripWhiteSpace().length() * |
701 descendant->style()->specifiedFontSize(); | 711 descendant->style()->specifiedFontSize(); |
702 | 712 |
703 if (length >= minimumTextLengthToAutosize) { | 713 if (length >= minimumTextLengthToAutosize) { |
704 cluster->m_hasEnoughTextToAutosize = HasEnoughText; | 714 cluster->m_hasEnoughTextToAutosize = HasEnoughText; |
705 return true; | 715 return true; |
706 } | 716 } |
707 } | 717 } |
708 descendant = descendant->nextInPreOrder(root); | 718 descendant = descendant->nextInPreOrder(root); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
764 TextAutosizer::Cluster* TextAutosizer::maybeCreateCluster( | 774 TextAutosizer::Cluster* TextAutosizer::maybeCreateCluster( |
765 const LayoutBlock* block) { | 775 const LayoutBlock* block) { |
766 BlockFlags flags = classifyBlock(block); | 776 BlockFlags flags = classifyBlock(block); |
767 if (!(flags & POTENTIAL_ROOT)) | 777 if (!(flags & POTENTIAL_ROOT)) |
768 return nullptr; | 778 return nullptr; |
769 | 779 |
770 Cluster* parentCluster = | 780 Cluster* parentCluster = |
771 m_clusterStack.isEmpty() ? nullptr : currentCluster(); | 781 m_clusterStack.isEmpty() ? nullptr : currentCluster(); |
772 ASSERT(parentCluster || block->isLayoutView()); | 782 ASSERT(parentCluster || block->isLayoutView()); |
773 | 783 |
774 // If a non-independent block would not alter the SUPPRESSING flag, it doesn't
need to be a cluster. | 784 // If a non-independent block would not alter the SUPPRESSING flag, it doesn't |
| 785 // need to be a cluster. |
775 bool parentSuppresses = | 786 bool parentSuppresses = |
776 parentCluster && (parentCluster->m_flags & SUPPRESSING); | 787 parentCluster && (parentCluster->m_flags & SUPPRESSING); |
777 if (!(flags & INDEPENDENT) && !(flags & EXPLICIT_WIDTH) && | 788 if (!(flags & INDEPENDENT) && !(flags & EXPLICIT_WIDTH) && |
778 !!(flags & SUPPRESSING) == parentSuppresses) | 789 !!(flags & SUPPRESSING) == parentSuppresses) |
779 return nullptr; | 790 return nullptr; |
780 | 791 |
781 Cluster* cluster = | 792 Cluster* cluster = |
782 new Cluster(block, flags, parentCluster, getSupercluster(block)); | 793 new Cluster(block, flags, parentCluster, getSupercluster(block)); |
783 #ifdef AUTOSIZING_DOM_DEBUG_INFO | 794 #ifdef AUTOSIZING_DOM_DEBUG_INFO |
784 // Non-SUPPRESSING clusters are annotated in clusterMultiplier. | 795 // Non-SUPPRESSING clusters are annotated in clusterMultiplier. |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
899 float TextAutosizer::widthFromBlock(const LayoutBlock* block) const { | 910 float TextAutosizer::widthFromBlock(const LayoutBlock* block) const { |
900 RELEASE_ASSERT(block); | 911 RELEASE_ASSERT(block); |
901 RELEASE_ASSERT(block->style()); | 912 RELEASE_ASSERT(block->style()); |
902 | 913 |
903 if (!(block->isTable() || block->isTableCell() || block->isListItem())) | 914 if (!(block->isTable() || block->isTableCell() || block->isListItem())) |
904 return block->contentLogicalWidth().toFloat(); | 915 return block->contentLogicalWidth().toFloat(); |
905 | 916 |
906 if (!block->containingBlock()) | 917 if (!block->containingBlock()) |
907 return 0; | 918 return 0; |
908 | 919 |
909 // Tables may be inflated before computing their preferred widths. Try several
methods to | 920 // Tables may be inflated before computing their preferred widths. Try several |
910 // obtain a width, and fall back on a containing block's width. | 921 // methods to obtain a width, and fall back on a containing block's width. |
911 for (; block; block = block->containingBlock()) { | 922 for (; block; block = block->containingBlock()) { |
912 float width; | 923 float width; |
913 Length specifiedWidth = | 924 Length specifiedWidth = |
914 block->isTableCell() | 925 block->isTableCell() |
915 ? toLayoutTableCell(block)->styleOrColLogicalWidth() | 926 ? toLayoutTableCell(block)->styleOrColLogicalWidth() |
916 : block->style()->logicalWidth(); | 927 : block->style()->logicalWidth(); |
917 if (specifiedWidth.isFixed()) { | 928 if (specifiedWidth.isFixed()) { |
918 if ((width = specifiedWidth.value()) > 0) | 929 if ((width = specifiedWidth.value()) > 0) |
919 return width; | 930 return width; |
920 } | 931 } |
921 if (specifiedWidth.isPercentOrCalc()) { | 932 if (specifiedWidth.isPercentOrCalc()) { |
922 if (float containerWidth = | 933 if (float containerWidth = |
923 block->containingBlock()->contentLogicalWidth().toFloat()) { | 934 block->containingBlock()->contentLogicalWidth().toFloat()) { |
924 if ((width = floatValueForLength(specifiedWidth, containerWidth)) > 0) | 935 if ((width = floatValueForLength(specifiedWidth, containerWidth)) > 0) |
925 return width; | 936 return width; |
926 } | 937 } |
927 } | 938 } |
928 if ((width = block->contentLogicalWidth().toFloat()) > 0) | 939 if ((width = block->contentLogicalWidth().toFloat()) > 0) |
929 return width; | 940 return width; |
930 } | 941 } |
931 return 0; | 942 return 0; |
932 } | 943 } |
933 | 944 |
934 float TextAutosizer::multiplierFromBlock(const LayoutBlock* block) { | 945 float TextAutosizer::multiplierFromBlock(const LayoutBlock* block) { |
935 // If block->needsLayout() is false, it does not need to be in m_blocksThatHav
eBegunLayout. | 946 // If block->needsLayout() is false, it does not need to be in |
936 // This can happen during layout of a positioned object if the cluster's DBCAT
is deeper | 947 // m_blocksThatHaveBegunLayout. This can happen during layout of a positioned |
937 // than the positioned object's containing block, and wasn't marked as needing
layout. | 948 // object if the cluster's DBCAT is deeper than the positioned object's |
| 949 // containing block, and wasn't marked as needing layout. |
938 ASSERT(m_blocksThatHaveBegunLayout.contains(block) || !block->needsLayout()); | 950 ASSERT(m_blocksThatHaveBegunLayout.contains(block) || !block->needsLayout()); |
939 | 951 |
940 // Block width, in CSS pixels. | 952 // Block width, in CSS pixels. |
941 float blockWidth = widthFromBlock(block); | 953 float blockWidth = widthFromBlock(block); |
942 float layoutWidth = | 954 float layoutWidth = |
943 std::min(blockWidth, static_cast<float>(m_pageInfo.m_layoutWidth)); | 955 std::min(blockWidth, static_cast<float>(m_pageInfo.m_layoutWidth)); |
944 float multiplier = | 956 float multiplier = |
945 m_pageInfo.m_frameWidth ? layoutWidth / m_pageInfo.m_frameWidth : 1.0f; | 957 m_pageInfo.m_frameWidth ? layoutWidth / m_pageInfo.m_frameWidth : 1.0f; |
946 multiplier *= m_pageInfo.m_accessibilityFontScaleFactor * | 958 multiplier *= m_pageInfo.m_accessibilityFontScaleFactor * |
947 m_pageInfo.m_deviceScaleAdjustment; | 959 m_pageInfo.m_deviceScaleAdjustment; |
(...skipping 14 matching lines...) Expand all Loading... |
962 const LayoutBlock* root) const { | 974 const LayoutBlock* root) const { |
963 size_t firstDepth = 0; | 975 size_t firstDepth = 0; |
964 const LayoutObject* firstTextLeaf = findTextLeaf(root, firstDepth, First); | 976 const LayoutObject* firstTextLeaf = findTextLeaf(root, firstDepth, First); |
965 if (!firstTextLeaf) | 977 if (!firstTextLeaf) |
966 return root; | 978 return root; |
967 | 979 |
968 size_t lastDepth = 0; | 980 size_t lastDepth = 0; |
969 const LayoutObject* lastTextLeaf = findTextLeaf(root, lastDepth, Last); | 981 const LayoutObject* lastTextLeaf = findTextLeaf(root, lastDepth, Last); |
970 ASSERT(lastTextLeaf); | 982 ASSERT(lastTextLeaf); |
971 | 983 |
972 // Equalize the depths if necessary. Only one of the while loops below will ge
t executed. | 984 // Equalize the depths if necessary. Only one of the while loops below will |
| 985 // get executed. |
973 const LayoutObject* firstNode = firstTextLeaf; | 986 const LayoutObject* firstNode = firstTextLeaf; |
974 const LayoutObject* lastNode = lastTextLeaf; | 987 const LayoutObject* lastNode = lastTextLeaf; |
975 while (firstDepth > lastDepth) { | 988 while (firstDepth > lastDepth) { |
976 firstNode = firstNode->parent(); | 989 firstNode = firstNode->parent(); |
977 --firstDepth; | 990 --firstDepth; |
978 } | 991 } |
979 while (lastDepth > firstDepth) { | 992 while (lastDepth > firstDepth) { |
980 lastNode = lastNode->parent(); | 993 lastNode = lastNode->parent(); |
981 --lastDepth; | 994 --lastDepth; |
982 } | 995 } |
983 | 996 |
984 // Go up from both nodes until the parent is the same. Both pointers will poin
t to the LCA then. | 997 // Go up from both nodes until the parent is the same. Both pointers will |
| 998 // point to the LCA then. |
985 while (firstNode != lastNode) { | 999 while (firstNode != lastNode) { |
986 firstNode = firstNode->parent(); | 1000 firstNode = firstNode->parent(); |
987 lastNode = lastNode->parent(); | 1001 lastNode = lastNode->parent(); |
988 } | 1002 } |
989 | 1003 |
990 if (firstNode->isLayoutBlock()) | 1004 if (firstNode->isLayoutBlock()) |
991 return toLayoutBlock(firstNode); | 1005 return toLayoutBlock(firstNode); |
992 | 1006 |
993 // containingBlock() should never leave the cluster, since it only skips ances
tors when finding | 1007 // containingBlock() should never leave the cluster, since it only skips |
994 // the container of position:absolute/fixed blocks, and those cannot exist bet
ween a cluster and | 1008 // ancestors when finding the container of position:absolute/fixed blocks, and |
995 // its text node's lowest common ancestor as isAutosizingCluster would have ma
de them into their | 1009 // those cannot exist between a cluster and its text node's lowest common |
996 // own independent cluster. | 1010 // ancestor as isAutosizingCluster would have made them into their own |
| 1011 // independent cluster. |
997 const LayoutBlock* containingBlock = firstNode->containingBlock(); | 1012 const LayoutBlock* containingBlock = firstNode->containingBlock(); |
998 if (!containingBlock) | 1013 if (!containingBlock) |
999 return root; | 1014 return root; |
1000 | 1015 |
1001 ASSERT(containingBlock->isDescendantOf(root)); | 1016 ASSERT(containingBlock->isDescendantOf(root)); |
1002 return containingBlock; | 1017 return containingBlock; |
1003 } | 1018 } |
1004 | 1019 |
1005 const LayoutObject* TextAutosizer::findTextLeaf( | 1020 const LayoutObject* TextAutosizer::findTextLeaf( |
1006 const LayoutObject* parent, | 1021 const LayoutObject* parent, |
1007 size_t& depth, | 1022 size_t& depth, |
1008 TextLeafSearch firstOrLast) const { | 1023 TextLeafSearch firstOrLast) const { |
1009 // List items are treated as text due to the marker. | 1024 // List items are treated as text due to the marker. |
1010 if (parent->isListItem()) | 1025 if (parent->isListItem()) |
1011 return parent; | 1026 return parent; |
1012 | 1027 |
1013 if (parent->isText()) | 1028 if (parent->isText()) |
1014 return parent; | 1029 return parent; |
1015 | 1030 |
1016 ++depth; | 1031 ++depth; |
1017 const LayoutObject* child = (firstOrLast == First) ? parent->slowFirstChild() | 1032 const LayoutObject* child = (firstOrLast == First) ? parent->slowFirstChild() |
1018 : parent->slowLastChild(); | 1033 : parent->slowLastChild(); |
1019 while (child) { | 1034 while (child) { |
1020 // Note: At this point clusters may not have been created for these blocks s
o we cannot rely | 1035 // Note: At this point clusters may not have been created for these blocks |
1021 // on m_clusters. Instead, we use a best-guess about whether the block
will become a cluster. | 1036 // so we cannot rely on m_clusters. Instead, we use a best-guess about |
| 1037 // whether the block will become a cluster. |
1022 if (!classifyBlock(child, INDEPENDENT)) { | 1038 if (!classifyBlock(child, INDEPENDENT)) { |
1023 if (const LayoutObject* leaf = findTextLeaf(child, depth, firstOrLast)) | 1039 if (const LayoutObject* leaf = findTextLeaf(child, depth, firstOrLast)) |
1024 return leaf; | 1040 return leaf; |
1025 } | 1041 } |
1026 child = (firstOrLast == First) ? child->nextSibling() | 1042 child = (firstOrLast == First) ? child->nextSibling() |
1027 : child->previousSibling(); | 1043 : child->previousSibling(); |
1028 } | 1044 } |
1029 --depth; | 1045 --depth; |
1030 | 1046 |
1031 return nullptr; | 1047 return nullptr; |
1032 } | 1048 } |
1033 | 1049 |
1034 void TextAutosizer::applyMultiplier(LayoutObject* layoutObject, | 1050 void TextAutosizer::applyMultiplier(LayoutObject* layoutObject, |
1035 float multiplier, | 1051 float multiplier, |
1036 SubtreeLayoutScope* layouter, | 1052 SubtreeLayoutScope* layouter, |
1037 RelayoutBehavior relayoutBehavior) { | 1053 RelayoutBehavior relayoutBehavior) { |
1038 ASSERT(layoutObject); | 1054 ASSERT(layoutObject); |
1039 ComputedStyle& currentStyle = layoutObject->mutableStyleRef(); | 1055 ComputedStyle& currentStyle = layoutObject->mutableStyleRef(); |
1040 if (!currentStyle.getTextSizeAdjust().isAuto()) { | 1056 if (!currentStyle.getTextSizeAdjust().isAuto()) { |
1041 // The accessibility font scale factor is applied by the autosizer so we nee
d to apply that | 1057 // The accessibility font scale factor is applied by the autosizer so we |
1042 // scale factor on top of the text-size-adjust multiplier. | 1058 // need to apply that scale factor on top of the text-size-adjust |
| 1059 // multiplier. |
1043 multiplier = currentStyle.getTextSizeAdjust().multiplier() * | 1060 multiplier = currentStyle.getTextSizeAdjust().multiplier() * |
1044 m_pageInfo.m_accessibilityFontScaleFactor; | 1061 m_pageInfo.m_accessibilityFontScaleFactor; |
1045 } else if (multiplier < 1) { | 1062 } else if (multiplier < 1) { |
1046 // Unlike text-size-adjust, the text autosizer should only inflate fonts. | 1063 // Unlike text-size-adjust, the text autosizer should only inflate fonts. |
1047 multiplier = 1; | 1064 multiplier = 1; |
1048 } | 1065 } |
1049 | 1066 |
1050 if (currentStyle.textAutosizingMultiplier() == multiplier) | 1067 if (currentStyle.textAutosizingMultiplier() == multiplier) |
1051 return; | 1068 return; |
1052 | 1069 |
1053 // We need to clone the layoutObject style to avoid breaking style sharing. | 1070 // We need to clone the layoutObject style to avoid breaking style sharing. |
1054 RefPtr<ComputedStyle> style = ComputedStyle::clone(currentStyle); | 1071 RefPtr<ComputedStyle> style = ComputedStyle::clone(currentStyle); |
1055 style->setTextAutosizingMultiplier(multiplier); | 1072 style->setTextAutosizingMultiplier(multiplier); |
1056 style->setUnique(); | 1073 style->setUnique(); |
1057 | 1074 |
1058 switch (relayoutBehavior) { | 1075 switch (relayoutBehavior) { |
1059 case AlreadyInLayout: | 1076 case AlreadyInLayout: |
1060 // Don't free currentStyle until the end of the layout pass. This allows o
ther parts of the system | 1077 // Don't free currentStyle until the end of the layout pass. This allows |
1061 // to safely hold raw ComputedStyle* pointers during layout, e.g. Breaking
Context::m_currentStyle. | 1078 // other parts of the system to safely hold raw ComputedStyle* pointers |
| 1079 // during layout, e.g. BreakingContext::m_currentStyle. |
1062 m_stylesRetainedDuringLayout.append(¤tStyle); | 1080 m_stylesRetainedDuringLayout.append(¤tStyle); |
1063 | 1081 |
1064 layoutObject->setStyleInternal(style.release()); | 1082 layoutObject->setStyleInternal(style.release()); |
1065 DCHECK(!layouter || layoutObject->isDescendantOf(&layouter->root())); | 1083 DCHECK(!layouter || layoutObject->isDescendantOf(&layouter->root())); |
1066 layoutObject->setNeedsLayoutAndFullPaintInvalidation( | 1084 layoutObject->setNeedsLayoutAndFullPaintInvalidation( |
1067 LayoutInvalidationReason::TextAutosizing, MarkContainerChain, | 1085 LayoutInvalidationReason::TextAutosizing, MarkContainerChain, |
1068 layouter); | 1086 layouter); |
1069 break; | 1087 break; |
1070 | 1088 |
1071 case LayoutNeeded: | 1089 case LayoutNeeded: |
(...skipping 16 matching lines...) Expand all Loading... |
1088 const LayoutBlock* parentDeepestBlockContainingAllText = | 1106 const LayoutBlock* parentDeepestBlockContainingAllText = |
1089 deepestBlockContainingAllText(cluster->m_parent); | 1107 deepestBlockContainingAllText(cluster->m_parent); |
1090 ASSERT(m_blocksThatHaveBegunLayout.contains(cluster->m_root)); | 1108 ASSERT(m_blocksThatHaveBegunLayout.contains(cluster->m_root)); |
1091 ASSERT(m_blocksThatHaveBegunLayout.contains( | 1109 ASSERT(m_blocksThatHaveBegunLayout.contains( |
1092 parentDeepestBlockContainingAllText)); | 1110 parentDeepestBlockContainingAllText)); |
1093 | 1111 |
1094 float contentWidth = cluster->m_root->contentLogicalWidth().toFloat(); | 1112 float contentWidth = cluster->m_root->contentLogicalWidth().toFloat(); |
1095 float clusterTextWidth = | 1113 float clusterTextWidth = |
1096 parentDeepestBlockContainingAllText->contentLogicalWidth().toFloat(); | 1114 parentDeepestBlockContainingAllText->contentLogicalWidth().toFloat(); |
1097 | 1115 |
1098 // Clusters with a root that is wider than the deepestBlockContainingAllText o
f their parent | 1116 // Clusters with a root that is wider than the deepestBlockContainingAllText |
1099 // autosize independently of their parent. | 1117 // of their parent autosize independently of their parent. |
1100 if (contentWidth > clusterTextWidth) | 1118 if (contentWidth > clusterTextWidth) |
1101 return true; | 1119 return true; |
1102 | 1120 |
1103 // Clusters with a root that is significantly narrower than the deepestBlockCo
ntainingAllText of | 1121 // Clusters with a root that is significantly narrower than the |
1104 // their parent autosize independently of their parent. | 1122 // deepestBlockContainingAllText of their parent autosize independently of |
| 1123 // their parent. |
1105 static float narrowWidthDifference = 200; | 1124 static float narrowWidthDifference = 200; |
1106 if (clusterTextWidth - contentWidth > narrowWidthDifference) | 1125 if (clusterTextWidth - contentWidth > narrowWidthDifference) |
1107 return true; | 1126 return true; |
1108 | 1127 |
1109 return false; | 1128 return false; |
1110 } | 1129 } |
1111 | 1130 |
1112 TextAutosizer::Cluster* TextAutosizer::currentCluster() const { | 1131 TextAutosizer::Cluster* TextAutosizer::currentCluster() const { |
1113 ASSERT_WITH_SECURITY_IMPLICATION(!m_clusterStack.isEmpty()); | 1132 ASSERT_WITH_SECURITY_IMPLICATION(!m_clusterStack.isEmpty()); |
1114 return m_clusterStack.last().get(); | 1133 return m_clusterStack.last().get(); |
1115 } | 1134 } |
1116 | 1135 |
1117 TextAutosizer::Cluster::Cluster(const LayoutBlock* root, | 1136 TextAutosizer::Cluster::Cluster(const LayoutBlock* root, |
1118 BlockFlags flags, | 1137 BlockFlags flags, |
1119 Cluster* parent, | 1138 Cluster* parent, |
1120 Supercluster* supercluster) | 1139 Supercluster* supercluster) |
1121 : m_root(root), | 1140 : m_root(root), |
1122 m_flags(flags), | 1141 m_flags(flags), |
1123 m_deepestBlockContainingAllText(nullptr), | 1142 m_deepestBlockContainingAllText(nullptr), |
1124 m_parent(parent), | 1143 m_parent(parent), |
1125 m_multiplier(0), | 1144 m_multiplier(0), |
1126 m_hasEnoughTextToAutosize(UnknownAmountOfText), | 1145 m_hasEnoughTextToAutosize(UnknownAmountOfText), |
1127 m_supercluster(supercluster), | 1146 m_supercluster(supercluster), |
1128 m_hasTableAncestor(root->isTableCell() || | 1147 m_hasTableAncestor(root->isTableCell() || |
1129 (m_parent && m_parent->m_hasTableAncestor)) {} | 1148 (m_parent && m_parent->m_hasTableAncestor)) {} |
1130 | 1149 |
1131 #if ENABLE(ASSERT) | 1150 #if ENABLE(ASSERT) |
1132 void TextAutosizer::FingerprintMapper::assertMapsAreConsistent() { | 1151 void TextAutosizer::FingerprintMapper::assertMapsAreConsistent() { |
1133 // For each fingerprint -> block mapping in m_blocksForFingerprint we should h
ave an associated | 1152 // For each fingerprint -> block mapping in m_blocksForFingerprint we should |
1134 // map from block -> fingerprint in m_fingerprints. | 1153 // have an associated map from block -> fingerprint in m_fingerprints. |
1135 ReverseFingerprintMap::iterator end = m_blocksForFingerprint.end(); | 1154 ReverseFingerprintMap::iterator end = m_blocksForFingerprint.end(); |
1136 for (ReverseFingerprintMap::iterator fingerprintIt = | 1155 for (ReverseFingerprintMap::iterator fingerprintIt = |
1137 m_blocksForFingerprint.begin(); | 1156 m_blocksForFingerprint.begin(); |
1138 fingerprintIt != end; ++fingerprintIt) { | 1157 fingerprintIt != end; ++fingerprintIt) { |
1139 Fingerprint fingerprint = fingerprintIt->key; | 1158 Fingerprint fingerprint = fingerprintIt->key; |
1140 BlockSet* blocks = fingerprintIt->value.get(); | 1159 BlockSet* blocks = fingerprintIt->value.get(); |
1141 for (BlockSet::iterator blockIt = blocks->begin(); blockIt != blocks->end(); | 1160 for (BlockSet::iterator blockIt = blocks->begin(); blockIt != blocks->end(); |
1142 ++blockIt) { | 1161 ++blockIt) { |
1143 const LayoutBlock* block = (*blockIt); | 1162 const LayoutBlock* block = (*blockIt); |
1144 ASSERT(m_fingerprints.get(block) == fingerprint); | 1163 ASSERT(m_fingerprints.get(block) == fingerprint); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1258 // multiplier; hence for specifiedSize == pleasantSize, computedSize will be | 1277 // multiplier; hence for specifiedSize == pleasantSize, computedSize will be |
1259 // multiplier * pleasantSize. For greater specifiedSizes we want to | 1278 // multiplier * pleasantSize. For greater specifiedSizes we want to |
1260 // gradually fade out the multiplier, so for every 1px increase in | 1279 // gradually fade out the multiplier, so for every 1px increase in |
1261 // specifiedSize beyond pleasantSize we will only increase computedSize | 1280 // specifiedSize beyond pleasantSize we will only increase computedSize |
1262 // by gradientAfterPleasantSize px until we meet the | 1281 // by gradientAfterPleasantSize px until we meet the |
1263 // computedSize = specifiedSize line, after which we stay on that line (so | 1282 // computedSize = specifiedSize line, after which we stay on that line (so |
1264 // then every 1px increase in specifiedSize increases computedSize by 1px). | 1283 // then every 1px increase in specifiedSize increases computedSize by 1px). |
1265 const float gradientAfterPleasantSize = 0.5; | 1284 const float gradientAfterPleasantSize = 0.5; |
1266 | 1285 |
1267 float computedSize; | 1286 float computedSize; |
1268 // Skip linear backoff for multipliers that shrink the size or when the font s
izes are small. | 1287 // Skip linear backoff for multipliers that shrink the size or when the font |
| 1288 // sizes are small. |
1269 if (multiplier <= 1 || specifiedSize <= pleasantSize) { | 1289 if (multiplier <= 1 || specifiedSize <= pleasantSize) { |
1270 computedSize = multiplier * specifiedSize; | 1290 computedSize = multiplier * specifiedSize; |
1271 } else { | 1291 } else { |
1272 computedSize = multiplier * pleasantSize + | 1292 computedSize = multiplier * pleasantSize + |
1273 gradientAfterPleasantSize * (specifiedSize - pleasantSize); | 1293 gradientAfterPleasantSize * (specifiedSize - pleasantSize); |
1274 if (computedSize < specifiedSize) | 1294 if (computedSize < specifiedSize) |
1275 computedSize = specifiedSize; | 1295 computedSize = specifiedSize; |
1276 } | 1296 } |
1277 return computedSize; | 1297 return computedSize; |
1278 } | 1298 } |
1279 | 1299 |
1280 DEFINE_TRACE(TextAutosizer) { | 1300 DEFINE_TRACE(TextAutosizer) { |
1281 visitor->trace(m_document); | 1301 visitor->trace(m_document); |
1282 } | 1302 } |
1283 | 1303 |
1284 } // namespace blink | 1304 } // namespace blink |
OLD | NEW |