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) |