Chromium Code Reviews| Index: Source/core/rendering/FastTextAutosizer.cpp |
| diff --git a/Source/core/rendering/FastTextAutosizer.cpp b/Source/core/rendering/FastTextAutosizer.cpp |
| index 37979f9c8caf8e032a321b57c295068e20c88160..ac6ca6b79772b0632419439c3a633de7db20ea91 100644 |
| --- a/Source/core/rendering/FastTextAutosizer.cpp |
| +++ b/Source/core/rendering/FastTextAutosizer.cpp |
| @@ -97,8 +97,8 @@ void FastTextAutosizer::beginLayout(RenderBlock* block) |
| return; |
| } |
| - if (Cluster* cluster = maybeGetOrCreateCluster(block)) |
| - m_clusterStack.append(cluster); |
| + if (Cluster* cluster = maybeCreateCluster(block)) |
| + m_clusterStack.append(adoptPtr(cluster)); |
| if (block->childrenInline()) |
| inflate(block); |
| @@ -124,10 +124,13 @@ void FastTextAutosizer::endLayout(RenderBlock* block) |
| { |
| if (!enabled()) |
| return; |
| + |
| + if (block->isRenderView()) { |
| + m_superclusters.clear(); |
| #ifndef NDEBUG |
| - if (block->isRenderView()) |
| m_blocksThatHaveBegunLayout.clear(); |
| #endif |
| + } |
| if (currentCluster()->m_root == block) |
| m_clusterStack.removeLast(); |
| @@ -222,12 +225,6 @@ float FastTextAutosizer::textLength(Cluster* cluster) |
| // clusters-sufficient-text-except-in-root.html). This currently includes text |
| // from descendant clusters. |
| - if (descendant->isRenderBlock() && m_clusters.contains(toRenderBlock(descendant))) { |
| - length += textLength(m_clusters.get(toRenderBlock(descendant))); |
| - descendant = descendant->nextInPreOrderAfterChildren(root); |
| - continue; |
| - } |
| - |
| if (measureLocalText && descendant->isText()) { |
| // Note: Using text().stripWhiteSpace().length() instead of renderedTextLength() because |
| // the lineboxes will not be built until layout. These values can be different. |
| @@ -245,7 +242,7 @@ AtomicString FastTextAutosizer::computeFingerprint(const RenderBlock* block) |
| return nullAtom; |
| } |
| -FastTextAutosizer::Cluster* FastTextAutosizer::maybeGetOrCreateCluster(const RenderBlock* block) |
| +FastTextAutosizer::Cluster* FastTextAutosizer::maybeCreateCluster(const RenderBlock* block) |
| { |
| if (!TextAutosizer::isAutosizingContainer(block)) |
| return 0; |
| @@ -262,32 +259,26 @@ FastTextAutosizer::Cluster* FastTextAutosizer::maybeGetOrCreateCluster(const Ren |
| if (!createClusterThatMightAutosize && containerCanAutosize == parentClusterCanAutosize) |
| return 0; |
| - ClusterMap::AddResult addResult = m_clusters.add(block, PassOwnPtr<Cluster>()); |
| - if (!addResult.isNewEntry) |
| - return addResult.iterator->value.get(); |
| - |
| - AtomicString fingerprint = m_fingerprintMapper.get(block); |
| - if (fingerprint.isNull()) { |
| - addResult.iterator->value = adoptPtr(new Cluster(block, containerCanAutosize, parentCluster)); |
| - return addResult.iterator->value.get(); |
| - } |
| - return addSupercluster(fingerprint, block); |
| + return new Cluster(block, containerCanAutosize, parentCluster, getSupercluster(block)); |
| } |
| -// FIXME: The supercluster logic does not work yet. |
| -FastTextAutosizer::Cluster* FastTextAutosizer::addSupercluster(AtomicString fingerprint, const RenderBlock* returnFor) |
| +FastTextAutosizer::Supercluster* FastTextAutosizer::getSupercluster(const RenderBlock* block) |
| { |
| - BlockSet& roots = m_fingerprintMapper.getBlocks(fingerprint); |
| + AtomicString fingerprint = m_fingerprintMapper.get(block); |
| + if (fingerprint.isNull()) |
| + return 0; |
| - Cluster* result = 0; |
| - for (BlockSet::iterator it = roots.begin(); it != roots.end(); ++it) { |
| - Cluster* cluster = new Cluster(*it, TextAutosizer::containerShouldBeAutosized(*it), currentCluster()); |
| - m_clusters.set(*it, adoptPtr(cluster)); |
| + BlockSet* roots = &m_fingerprintMapper.getBlocks(fingerprint); |
| + if (roots->size() < 2) |
| + return 0; |
| - if (*it == returnFor) |
| - result = cluster; |
| - } |
| - return result; |
| + SuperclusterMap::AddResult addResult = m_superclusters.add(fingerprint, PassOwnPtr<Supercluster>()); |
| + if (!addResult.isNewEntry) |
| + return addResult.iterator->value.get(); |
| + |
| + Supercluster* supercluster = new Supercluster(roots); |
| + addResult.iterator->value = adoptPtr(supercluster); |
| + return supercluster; |
| } |
| const RenderBlock* FastTextAutosizer::deepestCommonAncestor(BlockSet& blocks) |
| @@ -312,16 +303,10 @@ float FastTextAutosizer::clusterMultiplier(Cluster* cluster) |
| ASSERT(m_renderViewInfoPrepared); |
| if (!cluster->m_multiplier) { |
| if (TextAutosizer::isIndependentDescendant(cluster->m_root) || isWiderDescendant(cluster) || isNarrowerDescendant(cluster)) { |
| - if (clusterHasEnoughTextToAutosize(cluster)) { |
| - const RenderBlock* deepestBlockWithAllText = deepestBlockContainingAllText(cluster); |
| - |
| - // Ensure the deepest block containing all text has a valid contentLogicalWidth. |
| - ASSERT(m_blocksThatHaveBegunLayout.contains(deepestBlockWithAllText)); |
| - |
| - // Block width, in CSS pixels. |
| - float textBlockWidth = deepestBlockWithAllText->contentLogicalWidth(); |
| - float multiplier = min(textBlockWidth, static_cast<float>(m_layoutWidth)) / m_frameWidth; |
| - cluster->m_multiplier = max(m_baseMultiplier * multiplier, 1.0f); |
| + if (cluster->m_supercluster) { |
| + cluster->m_multiplier = superclusterMultiplier(cluster->m_supercluster); |
| + } else if (clusterHasEnoughTextToAutosize(cluster)) { |
| + cluster->m_multiplier = multiplierFromBlock(deepestBlockContainingAllText(cluster)); |
| } else { |
| cluster->m_multiplier = 1.0f; |
| } |
| @@ -333,6 +318,36 @@ float FastTextAutosizer::clusterMultiplier(Cluster* cluster) |
| return cluster->m_multiplier; |
| } |
| +float FastTextAutosizer::superclusterMultiplier(Supercluster* supercluster) |
| +{ |
| + if (!supercluster->m_multiplier) { |
| + const BlockSet* roots = supercluster->m_roots; |
| + BlockSet dbcats; |
|
pdr.
2014/02/06 22:03:27
Please add a comment explaining what a dbcat is, o
skobes
2014/02/06 23:55:50
Done.
|
| + for (BlockSet::iterator it = roots->begin(); it != roots->end(); ++it) { |
| + // This is a bit of a hack to let us compute dbcat and text length for |
|
pdr.
2014/02/06 22:03:27
The old autosizer used this hacky pattern quite a
skobes
2014/02/06 23:55:50
Done.
|
| + // clusters that don't technically exist yet. |
| + Cluster pseudocluster(*it, true, 0, supercluster); |
| + dbcats.add(deepestBlockContainingAllText(&pseudocluster)); |
| + supercluster->m_anyClusterHasEnoughText |= clusterHasEnoughTextToAutosize(&pseudocluster); |
| + } |
| + supercluster->m_multiplier = supercluster->m_anyClusterHasEnoughText |
| + ? multiplierFromBlock(deepestCommonAncestor(dbcats)) : 1.0f; |
| + } |
| + ASSERT(supercluster->m_multiplier); |
| + return supercluster->m_multiplier; |
| +} |
| + |
| +float FastTextAutosizer::multiplierFromBlock(const RenderBlock* block) |
| +{ |
| + ASSERT(m_blocksThatHaveBegunLayout.contains(block)); |
| + |
| + // Block width, in CSS pixels. |
| + float textBlockWidth = block->contentLogicalWidth(); |
| + float multiplier = min(textBlockWidth, static_cast<float>(m_layoutWidth)) / m_frameWidth; |
| + |
| + return max(m_baseMultiplier * multiplier, 1.0f); |
| +} |
| + |
| // FIXME: Refactor this to look more like FastTextAutosizer::deepestCommonAncestor. This is copied |
| // from TextAutosizer::findDeepestBlockContainingAllText. |
| const RenderBlock* FastTextAutosizer::deepestBlockContainingAllText(Cluster* cluster) |
| @@ -466,7 +481,7 @@ bool FastTextAutosizer::isNarrowerDescendant(Cluster* cluster) |
| FastTextAutosizer::Cluster* FastTextAutosizer::currentCluster() const |
| { |
| ASSERT(!m_clusterStack.isEmpty()); |
| - return m_clusterStack.last(); |
| + return m_clusterStack.last().get(); |
| } |
| void FastTextAutosizer::FingerprintMapper::add(const RenderBlock* block, AtomicString fingerprint) |