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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 virtual void performTask(ExecutionContext*) | 64 virtual void performTask(ExecutionContext*) |
65 { | 65 { |
66 m_element->setAttribute("data-autosizing", m_value, ASSERT_NO_EXCEPTION)
; | 66 m_element->setAttribute("data-autosizing", m_value, ASSERT_NO_EXCEPTION)
; |
67 } | 67 } |
68 | 68 |
69 private: | 69 private: |
70 RefPtrWillBePersistent<Element> m_element; | 70 RefPtrWillBePersistent<Element> m_element; |
71 AtomicString m_value; | 71 AtomicString m_value; |
72 }; | 72 }; |
73 | 73 |
74 static void writeDebugInfo(RenderObject* renderer, const AtomicString& output) | 74 static void writeDebugInfo(LayoutObject* renderer, const AtomicString& output) |
75 { | 75 { |
76 Node* node = renderer->node(); | 76 Node* node = renderer->node(); |
77 if (!node) | 77 if (!node) |
78 return; | 78 return; |
79 if (node->isDocumentNode()) | 79 if (node->isDocumentNode()) |
80 node = toDocument(node)->documentElement(); | 80 node = toDocument(node)->documentElement(); |
81 if (!node->isElementNode()) | 81 if (!node->isElementNode()) |
82 return; | 82 return; |
83 node->document().postTask(adoptPtr(new WriteDebugInfoTask(toElement(node), o
utput))); | 83 node->document().postTask(adoptPtr(new WriteDebugInfoTask(toElement(node), o
utput))); |
84 } | 84 } |
(...skipping 23 matching lines...) Expand all Loading... |
108 pageInfo = String::format("; pageinfo: bm %f * (lw %d / fw %d)", | 108 pageInfo = String::format("; pageinfo: bm %f * (lw %d / fw %d)", |
109 m_pageInfo.m_baseMultiplier, m_pageInfo.m_layoutWidth, m_pageInfo.m_
frameWidth); | 109 m_pageInfo.m_baseMultiplier, m_pageInfo.m_layoutWidth, m_pageInfo.m_
frameWidth); |
110 } | 110 } |
111 float multiplier = cluster->m_flags & SUPPRESSING ? 1.0 : cluster->m_multipl
ier; | 111 float multiplier = cluster->m_flags & SUPPRESSING ? 1.0 : cluster->m_multipl
ier; |
112 writeDebugInfo(const_cast<RenderBlock*>(cluster->m_root), | 112 writeDebugInfo(const_cast<RenderBlock*>(cluster->m_root), |
113 AtomicString(String::format("cluster: %f %s%s", multiplier, | 113 AtomicString(String::format("cluster: %f %s%s", multiplier, |
114 explanation.utf8().data(), pageInfo.utf8().data()))); | 114 explanation.utf8().data(), pageInfo.utf8().data()))); |
115 } | 115 } |
116 #endif | 116 #endif |
117 | 117 |
118 static const RenderObject* parentElementRenderer(const RenderObject* renderer) | 118 static const LayoutObject* parentElementRenderer(const LayoutObject* renderer) |
119 { | 119 { |
120 // At style recalc, the renderer's parent may not be attached, | 120 // At style recalc, the renderer's parent may not be attached, |
121 // so we need to obtain this from the DOM tree. | 121 // so we need to obtain this from the DOM tree. |
122 const Node* node = renderer->node(); | 122 const Node* node = renderer->node(); |
123 if (!node) | 123 if (!node) |
124 return 0; | 124 return 0; |
125 | 125 |
126 // FIXME: This should be using NodeRenderingTraversal::parent(). | 126 // FIXME: This should be using NodeRenderingTraversal::parent(). |
127 if (Element* parent = node->parentElement()) | 127 if (Element* parent = node->parentElement()) |
128 return parent->renderer(); | 128 return parent->renderer(); |
129 return 0; | 129 return 0; |
130 } | 130 } |
131 | 131 |
132 static bool isNonTextAreaFormControl(const RenderObject* renderer) | 132 static bool isNonTextAreaFormControl(const LayoutObject* renderer) |
133 { | 133 { |
134 const Node* node = renderer ? renderer->node() : 0; | 134 const Node* node = renderer ? renderer->node() : 0; |
135 if (!node || !node->isElementNode()) | 135 if (!node || !node->isElementNode()) |
136 return false; | 136 return false; |
137 const Element* element = toElement(node); | 137 const Element* element = toElement(node); |
138 | 138 |
139 return (element->isFormControlElement() && !isHTMLTextAreaElement(element)); | 139 return (element->isFormControlElement() && !isHTMLTextAreaElement(element)); |
140 } | 140 } |
141 | 141 |
142 static bool isPotentialClusterRoot(const RenderObject* renderer) | 142 static bool isPotentialClusterRoot(const LayoutObject* renderer) |
143 { | 143 { |
144 // "Potential cluster roots" are the smallest unit for which we can | 144 // "Potential cluster roots" are the smallest unit for which we can |
145 // enable/disable text autosizing. | 145 // enable/disable text autosizing. |
146 // - Must not be inline, as different multipliers on one line looks terrible
. | 146 // - Must not be inline, as different multipliers on one line looks terrible
. |
147 // Exceptions are inline-block and alike elements (inline-table, -webkit-i
nline-*), | 147 // Exceptions are inline-block and alike elements (inline-table, -webkit-i
nline-*), |
148 // as they often contain entire multi-line columns of text. | 148 // as they often contain entire multi-line columns of text. |
149 // - Must not be normal list items, as items in the same list should look | 149 // - Must not be normal list items, as items in the same list should look |
150 // consistent, unless they are floating or position:absolute/fixed. | 150 // consistent, unless they are floating or position:absolute/fixed. |
151 Node* node = renderer->generatingNode(); | 151 Node* node = renderer->generatingNode(); |
152 if (node && !node->hasChildren()) | 152 if (node && !node->hasChildren()) |
(...skipping 29 matching lines...) Expand all Loading... |
182 static bool blockIsRowOfLinks(const RenderBlock* block) | 182 static bool blockIsRowOfLinks(const RenderBlock* block) |
183 { | 183 { |
184 // A "row of links" is a block for which: | 184 // A "row of links" is a block for which: |
185 // 1. It does not contain non-link text elements longer than 3 characters | 185 // 1. It does not contain non-link text elements longer than 3 characters |
186 // 2. It contains a minimum of 3 inline links and all links should | 186 // 2. It contains a minimum of 3 inline links and all links should |
187 // have the same specified font size. | 187 // have the same specified font size. |
188 // 3. It should not contain <br> elements. | 188 // 3. It should not contain <br> elements. |
189 // 4. It should contain only inline elements unless they are containers, | 189 // 4. It should contain only inline elements unless they are containers, |
190 // children of link elements or children of sub-containers. | 190 // children of link elements or children of sub-containers. |
191 int linkCount = 0; | 191 int linkCount = 0; |
192 RenderObject* renderer = block->firstChild(); | 192 LayoutObject* renderer = block->firstChild(); |
193 float matchingFontSize = -1; | 193 float matchingFontSize = -1; |
194 | 194 |
195 while (renderer) { | 195 while (renderer) { |
196 if (!isPotentialClusterRoot(renderer)) { | 196 if (!isPotentialClusterRoot(renderer)) { |
197 if (renderer->isText() && toRenderText(renderer)->text().stripWhiteS
pace().length() > 3) | 197 if (renderer->isText() && toRenderText(renderer)->text().stripWhiteS
pace().length() > 3) |
198 return false; | 198 return false; |
199 if (!renderer->isInline() || renderer->isBR()) | 199 if (!renderer->isInline() || renderer->isBR()) |
200 return false; | 200 return false; |
201 } | 201 } |
202 if (renderer->style()->isLink()) { | 202 if (renderer->style()->isLink()) { |
(...skipping 30 matching lines...) Expand all Loading... |
233 if (block->isFloating()) | 233 if (block->isFloating()) |
234 return false; | 234 return false; |
235 } | 235 } |
236 return false; | 236 return false; |
237 } | 237 } |
238 | 238 |
239 static bool blockOrImmediateChildrenAreFormControls(const RenderBlock* block) | 239 static bool blockOrImmediateChildrenAreFormControls(const RenderBlock* block) |
240 { | 240 { |
241 if (isNonTextAreaFormControl(block)) | 241 if (isNonTextAreaFormControl(block)) |
242 return true; | 242 return true; |
243 const RenderObject* renderer = block->firstChild(); | 243 const LayoutObject* renderer = block->firstChild(); |
244 while (renderer) { | 244 while (renderer) { |
245 if (isNonTextAreaFormControl(renderer)) | 245 if (isNonTextAreaFormControl(renderer)) |
246 return true; | 246 return true; |
247 renderer = renderer->nextSibling(); | 247 renderer = renderer->nextSibling(); |
248 } | 248 } |
249 | 249 |
250 return false; | 250 return false; |
251 } | 251 } |
252 | 252 |
253 // Some blocks are not autosized even if their parent cluster wants them to. | 253 // Some blocks are not autosized even if their parent cluster wants them to. |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 prepareClusterStack(block->parent()); | 333 prepareClusterStack(block->parent()); |
334 } else if (block == currentCluster()->m_root) { | 334 } else if (block == currentCluster()->m_root) { |
335 // Ignore beginLayout on the same block twice. | 335 // Ignore beginLayout on the same block twice. |
336 // This can happen with paginated overflow. | 336 // This can happen with paginated overflow. |
337 return StopLayout; | 337 return StopLayout; |
338 } | 338 } |
339 | 339 |
340 return ContinueLayout; | 340 return ContinueLayout; |
341 } | 341 } |
342 | 342 |
343 void TextAutosizer::prepareClusterStack(const RenderObject* renderer) | 343 void TextAutosizer::prepareClusterStack(const LayoutObject* renderer) |
344 { | 344 { |
345 if (!renderer) | 345 if (!renderer) |
346 return; | 346 return; |
347 prepareClusterStack(renderer->parent()); | 347 prepareClusterStack(renderer->parent()); |
348 | 348 |
349 if (renderer->isRenderBlock()) { | 349 if (renderer->isRenderBlock()) { |
350 const RenderBlock* block = toRenderBlock(renderer); | 350 const RenderBlock* block = toRenderBlock(renderer); |
351 #if ENABLE(ASSERT) | 351 #if ENABLE(ASSERT) |
352 m_blocksThatHaveBegunLayout.add(block); | 352 m_blocksThatHaveBegunLayout.add(block); |
353 #endif | 353 #endif |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 ASSERT(table); | 395 ASSERT(table); |
396 ASSERT(!table->style()->isFixedTableLayout()); | 396 ASSERT(!table->style()->isFixedTableLayout()); |
397 ASSERT(table->containingBlock()); | 397 ASSERT(table->containingBlock()); |
398 | 398 |
399 Cluster* cluster = currentCluster(); | 399 Cluster* cluster = currentCluster(); |
400 if (cluster->m_root != table) | 400 if (cluster->m_root != table) |
401 return; | 401 return; |
402 | 402 |
403 // Pre-inflate cells that have enough text so that their inflated preferred
widths will be used | 403 // Pre-inflate cells that have enough text so that their inflated preferred
widths will be used |
404 // for column sizing. | 404 // for column sizing. |
405 for (RenderObject* section = table->firstChild(); section; section = section
->nextSibling()) { | 405 for (LayoutObject* section = table->firstChild(); section; section = section
->nextSibling()) { |
406 if (!section->isTableSection()) | 406 if (!section->isTableSection()) |
407 continue; | 407 continue; |
408 for (LayoutTableRow* row = toLayoutTableSection(section)->firstRow(); ro
w; row = row->nextRow()) { | 408 for (LayoutTableRow* row = toLayoutTableSection(section)->firstRow(); ro
w; row = row->nextRow()) { |
409 for (LayoutTableCell* cell = row->firstCell(); cell; cell = cell->ne
xtCell()) { | 409 for (LayoutTableCell* cell = row->firstCell(); cell; cell = cell->ne
xtCell()) { |
410 if (!cell->needsLayout()) | 410 if (!cell->needsLayout()) |
411 continue; | 411 continue; |
412 | 412 |
413 beginLayout(cell); | 413 beginLayout(cell); |
414 inflate(cell, DescendToInnerBlocks); | 414 inflate(cell, DescendToInnerBlocks); |
415 endLayout(cell); | 415 endLayout(cell); |
(...skipping 14 matching lines...) Expand all Loading... |
430 #if ENABLE(ASSERT) | 430 #if ENABLE(ASSERT) |
431 m_blocksThatHaveBegunLayout.clear(); | 431 m_blocksThatHaveBegunLayout.clear(); |
432 #endif | 432 #endif |
433 // Tables can create two layout scopes for the same block so the isEmpty | 433 // Tables can create two layout scopes for the same block so the isEmpty |
434 // check below is needed to guard against endLayout being called twice. | 434 // check below is needed to guard against endLayout being called twice. |
435 } else if (!m_clusterStack.isEmpty() && currentCluster()->m_root == block) { | 435 } else if (!m_clusterStack.isEmpty() && currentCluster()->m_root == block) { |
436 m_clusterStack.removeLast(); | 436 m_clusterStack.removeLast(); |
437 } | 437 } |
438 } | 438 } |
439 | 439 |
440 float TextAutosizer::inflate(RenderObject* parent, InflateBehavior behavior, flo
at multiplier) | 440 float TextAutosizer::inflate(LayoutObject* parent, InflateBehavior behavior, flo
at multiplier) |
441 { | 441 { |
442 Cluster* cluster = currentCluster(); | 442 Cluster* cluster = currentCluster(); |
443 bool hasTextChild = false; | 443 bool hasTextChild = false; |
444 | 444 |
445 RenderObject* child = 0; | 445 LayoutObject* child = 0; |
446 if (parent->isRenderBlock() && (parent->childrenInline() || behavior == Desc
endToInnerBlocks)) | 446 if (parent->isRenderBlock() && (parent->childrenInline() || behavior == Desc
endToInnerBlocks)) |
447 child = toRenderBlock(parent)->firstChild(); | 447 child = toRenderBlock(parent)->firstChild(); |
448 else if (parent->isRenderInline()) | 448 else if (parent->isRenderInline()) |
449 child = toRenderInline(parent)->firstChild(); | 449 child = toRenderInline(parent)->firstChild(); |
450 | 450 |
451 while (child) { | 451 while (child) { |
452 if (child->isText()) { | 452 if (child->isText()) { |
453 hasTextChild = true; | 453 hasTextChild = true; |
454 // We only calculate this multiplier on-demand to ensure the parent
block of this text | 454 // We only calculate this multiplier on-demand to ensure the parent
block of this text |
455 // has entered layout. | 455 // has entered layout. |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 { | 562 { |
563 Page * page = m_document->page(); | 563 Page * page = m_document->page(); |
564 ASSERT(page); | 564 ASSERT(page); |
565 return page->settings().pinchVirtualViewportEnabled() ? | 565 return page->settings().pinchVirtualViewportEnabled() ? |
566 page->frameHost().pinchViewport().size() : | 566 page->frameHost().pinchViewport().size() : |
567 page->deprecatedLocalMainFrame()->view()->unscaledVisibleContentSize(Inc
ludeScrollbars); | 567 page->deprecatedLocalMainFrame()->view()->unscaledVisibleContentSize(Inc
ludeScrollbars); |
568 } | 568 } |
569 | 569 |
570 void TextAutosizer::resetMultipliers() | 570 void TextAutosizer::resetMultipliers() |
571 { | 571 { |
572 RenderObject* renderer = m_document->renderView(); | 572 LayoutObject* renderer = m_document->renderView(); |
573 while (renderer) { | 573 while (renderer) { |
574 if (RenderStyle* style = renderer->style()) { | 574 if (RenderStyle* style = renderer->style()) { |
575 if (style->textAutosizingMultiplier() != 1) | 575 if (style->textAutosizingMultiplier() != 1) |
576 applyMultiplier(renderer, 1, LayoutNeeded); | 576 applyMultiplier(renderer, 1, LayoutNeeded); |
577 } | 577 } |
578 renderer = renderer->nextInPreOrder(); | 578 renderer = renderer->nextInPreOrder(); |
579 } | 579 } |
580 } | 580 } |
581 | 581 |
582 void TextAutosizer::setAllTextNeedsLayout() | 582 void TextAutosizer::setAllTextNeedsLayout() |
583 { | 583 { |
584 RenderObject* renderer = m_document->renderView(); | 584 LayoutObject* renderer = m_document->renderView(); |
585 while (renderer) { | 585 while (renderer) { |
586 if (renderer->isText()) | 586 if (renderer->isText()) |
587 renderer->setNeedsLayoutAndFullPaintInvalidation(); | 587 renderer->setNeedsLayoutAndFullPaintInvalidation(); |
588 renderer = renderer->nextInPreOrder(); | 588 renderer = renderer->nextInPreOrder(); |
589 } | 589 } |
590 } | 590 } |
591 | 591 |
592 TextAutosizer::BlockFlags TextAutosizer::classifyBlock(const RenderObject* rende
rer, BlockFlags mask) const | 592 TextAutosizer::BlockFlags TextAutosizer::classifyBlock(const LayoutObject* rende
rer, BlockFlags mask) const |
593 { | 593 { |
594 if (!renderer->isRenderBlock()) | 594 if (!renderer->isRenderBlock()) |
595 return 0; | 595 return 0; |
596 | 596 |
597 const RenderBlock* block = toRenderBlock(renderer); | 597 const RenderBlock* block = toRenderBlock(renderer); |
598 BlockFlags flags = 0; | 598 BlockFlags flags = 0; |
599 | 599 |
600 if (isPotentialClusterRoot(block)) { | 600 if (isPotentialClusterRoot(block)) { |
601 if (mask & POTENTIAL_ROOT) | 601 if (mask & POTENTIAL_ROOT) |
602 flags |= POTENTIAL_ROOT; | 602 flags |= POTENTIAL_ROOT; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 | 636 |
637 if (cluster->m_flags & SUPPRESSING) { | 637 if (cluster->m_flags & SUPPRESSING) { |
638 cluster->m_hasEnoughTextToAutosize = NotEnoughText; | 638 cluster->m_hasEnoughTextToAutosize = NotEnoughText; |
639 return false; | 639 return false; |
640 } | 640 } |
641 | 641 |
642 // 4 lines of text is considered enough to autosize. | 642 // 4 lines of text is considered enough to autosize. |
643 float minimumTextLengthToAutosize = widthFromBlock(widthProvider) * 4; | 643 float minimumTextLengthToAutosize = widthFromBlock(widthProvider) * 4; |
644 | 644 |
645 float length = 0; | 645 float length = 0; |
646 RenderObject* descendant = root->firstChild(); | 646 LayoutObject* descendant = root->firstChild(); |
647 while (descendant) { | 647 while (descendant) { |
648 if (descendant->isRenderBlock()) { | 648 if (descendant->isRenderBlock()) { |
649 if (classifyBlock(descendant, INDEPENDENT | SUPPRESSING)) { | 649 if (classifyBlock(descendant, INDEPENDENT | SUPPRESSING)) { |
650 descendant = descendant->nextInPreOrderAfterChildren(root); | 650 descendant = descendant->nextInPreOrderAfterChildren(root); |
651 continue; | 651 continue; |
652 } | 652 } |
653 } else if (descendant->isText()) { | 653 } else if (descendant->isText()) { |
654 // Note: Using text().stripWhiteSpace().length() instead of rendered
TextLength() because | 654 // Note: Using text().stripWhiteSpace().length() instead of rendered
TextLength() because |
655 // the lineboxes will not be built until layout. These values can be
different. | 655 // the lineboxes will not be built until layout. These values can be
different. |
656 // Note: This is an approximation assuming each character is 1em wid
e. | 656 // Note: This is an approximation assuming each character is 1em wid
e. |
657 length += toRenderText(descendant)->text().stripWhiteSpace().length(
) * descendant->style()->specifiedFontSize(); | 657 length += toRenderText(descendant)->text().stripWhiteSpace().length(
) * descendant->style()->specifiedFontSize(); |
658 | 658 |
659 if (length >= minimumTextLengthToAutosize) { | 659 if (length >= minimumTextLengthToAutosize) { |
660 cluster->m_hasEnoughTextToAutosize = HasEnoughText; | 660 cluster->m_hasEnoughTextToAutosize = HasEnoughText; |
661 return true; | 661 return true; |
662 } | 662 } |
663 } | 663 } |
664 descendant = descendant->nextInPreOrder(root); | 664 descendant = descendant->nextInPreOrder(root); |
665 } | 665 } |
666 | 666 |
667 cluster->m_hasEnoughTextToAutosize = NotEnoughText; | 667 cluster->m_hasEnoughTextToAutosize = NotEnoughText; |
668 return false; | 668 return false; |
669 } | 669 } |
670 | 670 |
671 TextAutosizer::Fingerprint TextAutosizer::getFingerprint(const RenderObject* ren
derer) | 671 TextAutosizer::Fingerprint TextAutosizer::getFingerprint(const LayoutObject* ren
derer) |
672 { | 672 { |
673 Fingerprint result = m_fingerprintMapper.get(renderer); | 673 Fingerprint result = m_fingerprintMapper.get(renderer); |
674 if (!result) { | 674 if (!result) { |
675 result = computeFingerprint(renderer); | 675 result = computeFingerprint(renderer); |
676 m_fingerprintMapper.add(renderer, result); | 676 m_fingerprintMapper.add(renderer, result); |
677 } | 677 } |
678 return result; | 678 return result; |
679 } | 679 } |
680 | 680 |
681 TextAutosizer::Fingerprint TextAutosizer::computeFingerprint(const RenderObject*
renderer) | 681 TextAutosizer::Fingerprint TextAutosizer::computeFingerprint(const LayoutObject*
renderer) |
682 { | 682 { |
683 Node* node = renderer->generatingNode(); | 683 Node* node = renderer->generatingNode(); |
684 if (!node || !node->isElementNode()) | 684 if (!node || !node->isElementNode()) |
685 return 0; | 685 return 0; |
686 | 686 |
687 FingerprintSourceData data; | 687 FingerprintSourceData data; |
688 if (const RenderObject* parent = parentElementRenderer(renderer)) | 688 if (const LayoutObject* parent = parentElementRenderer(renderer)) |
689 data.m_parentHash = getFingerprint(parent); | 689 data.m_parentHash = getFingerprint(parent); |
690 | 690 |
691 data.m_qualifiedNameHash = QualifiedNameHash::hash(toElement(node)->tagQName
()); | 691 data.m_qualifiedNameHash = QualifiedNameHash::hash(toElement(node)->tagQName
()); |
692 | 692 |
693 if (RenderStyle* style = renderer->style()) { | 693 if (RenderStyle* style = renderer->style()) { |
694 data.m_packedStyleProperties = style->direction(); | 694 data.m_packedStyleProperties = style->direction(); |
695 data.m_packedStyleProperties |= (style->position() << 1); | 695 data.m_packedStyleProperties |= (style->position() << 1); |
696 data.m_packedStyleProperties |= (style->floating() << 4); | 696 data.m_packedStyleProperties |= (style->floating() << 4); |
697 data.m_packedStyleProperties |= (style->display() << 6); | 697 data.m_packedStyleProperties |= (style->display() << 6); |
698 data.m_packedStyleProperties |= (style->width().type() << 11); | 698 data.m_packedStyleProperties |= (style->width().type() << 11); |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 if (!cluster->m_deepestBlockContainingAllText) | 892 if (!cluster->m_deepestBlockContainingAllText) |
893 cluster->m_deepestBlockContainingAllText = deepestBlockContainingAllText
(cluster->m_root); | 893 cluster->m_deepestBlockContainingAllText = deepestBlockContainingAllText
(cluster->m_root); |
894 | 894 |
895 return cluster->m_deepestBlockContainingAllText; | 895 return cluster->m_deepestBlockContainingAllText; |
896 } | 896 } |
897 | 897 |
898 // FIXME: Refactor this to look more like TextAutosizer::deepestCommonAncestor. | 898 // FIXME: Refactor this to look more like TextAutosizer::deepestCommonAncestor. |
899 const RenderBlock* TextAutosizer::deepestBlockContainingAllText(const RenderBloc
k* root) const | 899 const RenderBlock* TextAutosizer::deepestBlockContainingAllText(const RenderBloc
k* root) const |
900 { | 900 { |
901 size_t firstDepth = 0; | 901 size_t firstDepth = 0; |
902 const RenderObject* firstTextLeaf = findTextLeaf(root, firstDepth, First); | 902 const LayoutObject* firstTextLeaf = findTextLeaf(root, firstDepth, First); |
903 if (!firstTextLeaf) | 903 if (!firstTextLeaf) |
904 return root; | 904 return root; |
905 | 905 |
906 size_t lastDepth = 0; | 906 size_t lastDepth = 0; |
907 const RenderObject* lastTextLeaf = findTextLeaf(root, lastDepth, Last); | 907 const LayoutObject* lastTextLeaf = findTextLeaf(root, lastDepth, Last); |
908 ASSERT(lastTextLeaf); | 908 ASSERT(lastTextLeaf); |
909 | 909 |
910 // Equalize the depths if necessary. Only one of the while loops below will
get executed. | 910 // Equalize the depths if necessary. Only one of the while loops below will
get executed. |
911 const RenderObject* firstNode = firstTextLeaf; | 911 const LayoutObject* firstNode = firstTextLeaf; |
912 const RenderObject* lastNode = lastTextLeaf; | 912 const LayoutObject* lastNode = lastTextLeaf; |
913 while (firstDepth > lastDepth) { | 913 while (firstDepth > lastDepth) { |
914 firstNode = firstNode->parent(); | 914 firstNode = firstNode->parent(); |
915 --firstDepth; | 915 --firstDepth; |
916 } | 916 } |
917 while (lastDepth > firstDepth) { | 917 while (lastDepth > firstDepth) { |
918 lastNode = lastNode->parent(); | 918 lastNode = lastNode->parent(); |
919 --lastDepth; | 919 --lastDepth; |
920 } | 920 } |
921 | 921 |
922 // Go up from both nodes until the parent is the same. Both pointers will po
int to the LCA then. | 922 // Go up from both nodes until the parent is the same. Both pointers will po
int to the LCA then. |
(...skipping 10 matching lines...) Expand all Loading... |
933 // its text node's lowest common ancestor as isAutosizingCluster would have
made them into their | 933 // its text node's lowest common ancestor as isAutosizingCluster would have
made them into their |
934 // own independent cluster. | 934 // own independent cluster. |
935 const RenderBlock* containingBlock = firstNode->containingBlock(); | 935 const RenderBlock* containingBlock = firstNode->containingBlock(); |
936 if (!containingBlock) | 936 if (!containingBlock) |
937 return root; | 937 return root; |
938 | 938 |
939 ASSERT(containingBlock->isDescendantOf(root)); | 939 ASSERT(containingBlock->isDescendantOf(root)); |
940 return containingBlock; | 940 return containingBlock; |
941 } | 941 } |
942 | 942 |
943 const RenderObject* TextAutosizer::findTextLeaf(const RenderObject* parent, size
_t& depth, TextLeafSearch firstOrLast) const | 943 const LayoutObject* TextAutosizer::findTextLeaf(const LayoutObject* parent, size
_t& depth, TextLeafSearch firstOrLast) const |
944 { | 944 { |
945 // List items are treated as text due to the marker. | 945 // List items are treated as text due to the marker. |
946 // The actual renderer for the marker (RenderListMarker) may not be in the t
ree yet since it is added during layout. | 946 // The actual renderer for the marker (RenderListMarker) may not be in the t
ree yet since it is added during layout. |
947 if (parent->isListItem()) | 947 if (parent->isListItem()) |
948 return parent; | 948 return parent; |
949 | 949 |
950 if (parent->isText()) | 950 if (parent->isText()) |
951 return parent; | 951 return parent; |
952 | 952 |
953 ++depth; | 953 ++depth; |
954 const RenderObject* child = (firstOrLast == First) ? parent->slowFirstChild(
) : parent->slowLastChild(); | 954 const LayoutObject* child = (firstOrLast == First) ? parent->slowFirstChild(
) : parent->slowLastChild(); |
955 while (child) { | 955 while (child) { |
956 // Note: At this point clusters may not have been created for these bloc
ks so we cannot rely | 956 // Note: At this point clusters may not have been created for these bloc
ks so we cannot rely |
957 // on m_clusters. Instead, we use a best-guess about whether the b
lock will become a cluster. | 957 // on m_clusters. Instead, we use a best-guess about whether the b
lock will become a cluster. |
958 if (!classifyBlock(child, INDEPENDENT)) { | 958 if (!classifyBlock(child, INDEPENDENT)) { |
959 if (const RenderObject* leaf = findTextLeaf(child, depth, firstOrLas
t)) | 959 if (const LayoutObject* leaf = findTextLeaf(child, depth, firstOrLas
t)) |
960 return leaf; | 960 return leaf; |
961 } | 961 } |
962 child = (firstOrLast == First) ? child->nextSibling() : child->previousS
ibling(); | 962 child = (firstOrLast == First) ? child->nextSibling() : child->previousS
ibling(); |
963 } | 963 } |
964 --depth; | 964 --depth; |
965 | 965 |
966 return 0; | 966 return 0; |
967 } | 967 } |
968 | 968 |
969 void TextAutosizer::applyMultiplier(RenderObject* renderer, float multiplier, Re
layoutBehavior relayoutBehavior) | 969 void TextAutosizer::applyMultiplier(LayoutObject* renderer, float multiplier, Re
layoutBehavior relayoutBehavior) |
970 { | 970 { |
971 ASSERT(renderer && renderer->style()); | 971 ASSERT(renderer && renderer->style()); |
972 RenderStyle* currentStyle = renderer->style(); | 972 RenderStyle* currentStyle = renderer->style(); |
973 if (currentStyle->textAutosizingMultiplier() == multiplier) | 973 if (currentStyle->textAutosizingMultiplier() == multiplier) |
974 return; | 974 return; |
975 | 975 |
976 // We need to clone the render style to avoid breaking style sharing. | 976 // We need to clone the render style to avoid breaking style sharing. |
977 RefPtr<RenderStyle> style = RenderStyle::clone(currentStyle); | 977 RefPtr<RenderStyle> style = RenderStyle::clone(currentStyle); |
978 style->setTextAutosizingMultiplier(multiplier); | 978 style->setTextAutosizingMultiplier(multiplier); |
979 style->setUnique(); | 979 style->setUnique(); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1040 Fingerprint fingerprint = fingerprintIt->key; | 1040 Fingerprint fingerprint = fingerprintIt->key; |
1041 BlockSet* blocks = fingerprintIt->value.get(); | 1041 BlockSet* blocks = fingerprintIt->value.get(); |
1042 for (BlockSet::iterator blockIt = blocks->begin(); blockIt != blocks->en
d(); ++blockIt) { | 1042 for (BlockSet::iterator blockIt = blocks->begin(); blockIt != blocks->en
d(); ++blockIt) { |
1043 const RenderBlock* block = (*blockIt); | 1043 const RenderBlock* block = (*blockIt); |
1044 ASSERT(m_fingerprints.get(block) == fingerprint); | 1044 ASSERT(m_fingerprints.get(block) == fingerprint); |
1045 } | 1045 } |
1046 } | 1046 } |
1047 } | 1047 } |
1048 #endif | 1048 #endif |
1049 | 1049 |
1050 void TextAutosizer::FingerprintMapper::add(const RenderObject* renderer, Fingerp
rint fingerprint) | 1050 void TextAutosizer::FingerprintMapper::add(const LayoutObject* renderer, Fingerp
rint fingerprint) |
1051 { | 1051 { |
1052 remove(renderer); | 1052 remove(renderer); |
1053 | 1053 |
1054 m_fingerprints.set(renderer, fingerprint); | 1054 m_fingerprints.set(renderer, fingerprint); |
1055 #if ENABLE(ASSERT) | 1055 #if ENABLE(ASSERT) |
1056 assertMapsAreConsistent(); | 1056 assertMapsAreConsistent(); |
1057 #endif | 1057 #endif |
1058 } | 1058 } |
1059 | 1059 |
1060 void TextAutosizer::FingerprintMapper::addTentativeClusterRoot(const RenderBlock
* block, Fingerprint fingerprint) | 1060 void TextAutosizer::FingerprintMapper::addTentativeClusterRoot(const RenderBlock
* block, Fingerprint fingerprint) |
1061 { | 1061 { |
1062 add(block, fingerprint); | 1062 add(block, fingerprint); |
1063 | 1063 |
1064 ReverseFingerprintMap::AddResult addResult = m_blocksForFingerprint.add(fing
erprint, PassOwnPtr<BlockSet>()); | 1064 ReverseFingerprintMap::AddResult addResult = m_blocksForFingerprint.add(fing
erprint, PassOwnPtr<BlockSet>()); |
1065 if (addResult.isNewEntry) | 1065 if (addResult.isNewEntry) |
1066 addResult.storedValue->value = adoptPtr(new BlockSet); | 1066 addResult.storedValue->value = adoptPtr(new BlockSet); |
1067 addResult.storedValue->value->add(block); | 1067 addResult.storedValue->value->add(block); |
1068 #if ENABLE(ASSERT) | 1068 #if ENABLE(ASSERT) |
1069 assertMapsAreConsistent(); | 1069 assertMapsAreConsistent(); |
1070 #endif | 1070 #endif |
1071 } | 1071 } |
1072 | 1072 |
1073 bool TextAutosizer::FingerprintMapper::remove(const RenderObject* renderer) | 1073 bool TextAutosizer::FingerprintMapper::remove(const LayoutObject* renderer) |
1074 { | 1074 { |
1075 Fingerprint fingerprint = m_fingerprints.take(renderer); | 1075 Fingerprint fingerprint = m_fingerprints.take(renderer); |
1076 if (!fingerprint || !renderer->isRenderBlock()) | 1076 if (!fingerprint || !renderer->isRenderBlock()) |
1077 return false; | 1077 return false; |
1078 | 1078 |
1079 ReverseFingerprintMap::iterator blocksIter = m_blocksForFingerprint.find(fin
gerprint); | 1079 ReverseFingerprintMap::iterator blocksIter = m_blocksForFingerprint.find(fin
gerprint); |
1080 if (blocksIter == m_blocksForFingerprint.end()) | 1080 if (blocksIter == m_blocksForFingerprint.end()) |
1081 return false; | 1081 return false; |
1082 | 1082 |
1083 BlockSet& blocks = *blocksIter->value; | 1083 BlockSet& blocks = *blocksIter->value; |
1084 blocks.remove(toRenderBlock(renderer)); | 1084 blocks.remove(toRenderBlock(renderer)); |
1085 if (blocks.isEmpty()) | 1085 if (blocks.isEmpty()) |
1086 m_blocksForFingerprint.remove(blocksIter); | 1086 m_blocksForFingerprint.remove(blocksIter); |
1087 #if ENABLE(ASSERT) | 1087 #if ENABLE(ASSERT) |
1088 assertMapsAreConsistent(); | 1088 assertMapsAreConsistent(); |
1089 #endif | 1089 #endif |
1090 return true; | 1090 return true; |
1091 } | 1091 } |
1092 | 1092 |
1093 TextAutosizer::Fingerprint TextAutosizer::FingerprintMapper::get(const RenderObj
ect* renderer) | 1093 TextAutosizer::Fingerprint TextAutosizer::FingerprintMapper::get(const LayoutObj
ect* renderer) |
1094 { | 1094 { |
1095 return m_fingerprints.get(renderer); | 1095 return m_fingerprints.get(renderer); |
1096 } | 1096 } |
1097 | 1097 |
1098 TextAutosizer::BlockSet* TextAutosizer::FingerprintMapper::getTentativeClusterRo
ots(Fingerprint fingerprint) | 1098 TextAutosizer::BlockSet* TextAutosizer::FingerprintMapper::getTentativeClusterRo
ots(Fingerprint fingerprint) |
1099 { | 1099 { |
1100 return m_blocksForFingerprint.get(fingerprint); | 1100 return m_blocksForFingerprint.get(fingerprint); |
1101 } | 1101 } |
1102 | 1102 |
1103 TextAutosizer::LayoutScope::LayoutScope(RenderBlock* block) | 1103 TextAutosizer::LayoutScope::LayoutScope(RenderBlock* block) |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1174 } | 1174 } |
1175 return computedSize; | 1175 return computedSize; |
1176 } | 1176 } |
1177 | 1177 |
1178 void TextAutosizer::trace(Visitor* visitor) | 1178 void TextAutosizer::trace(Visitor* visitor) |
1179 { | 1179 { |
1180 visitor->trace(m_document); | 1180 visitor->trace(m_document); |
1181 } | 1181 } |
1182 | 1182 |
1183 } // namespace blink | 1183 } // namespace blink |
OLD | NEW |