summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/core/rendering/TextAutosizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/core/rendering/TextAutosizer.cpp')
-rw-r--r--chromium/third_party/WebKit/Source/core/rendering/TextAutosizer.cpp288
1 files changed, 226 insertions, 62 deletions
diff --git a/chromium/third_party/WebKit/Source/core/rendering/TextAutosizer.cpp b/chromium/third_party/WebKit/Source/core/rendering/TextAutosizer.cpp
index bc57d66cfab..290c008fa79 100644
--- a/chromium/third_party/WebKit/Source/core/rendering/TextAutosizer.cpp
+++ b/chromium/third_party/WebKit/Source/core/rendering/TextAutosizer.cpp
@@ -24,9 +24,11 @@
#include <algorithm>
#include "core/dom/Document.h"
-#include "core/html/HTMLElement.h"
-#include "core/inspector/InspectorInstrumentation.h"
+#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
+#include "core/frame/UseCounter.h"
+#include "core/html/HTMLElement.h"
+#include "core/page/Page.h"
#include "core/rendering/RenderListItem.h"
#include "core/rendering/RenderObject.h"
#include "core/rendering/RenderText.h"
@@ -36,10 +38,11 @@
#include "platform/TraceEvent.h"
#include "platform/geometry/IntSize.h"
#include "wtf/StdLibExtras.h"
-#include "wtf/Vector.h"
namespace WebCore {
+#define AUTOSIZING_CLUSTER_HASH
+
using namespace HTMLNames;
struct TextAutosizingWindowInfo {
@@ -47,26 +50,25 @@ struct TextAutosizingWindowInfo {
IntSize minLayoutSize;
};
-// Represents cluster related data. Instances should not persist between calls to processSubtree.
-struct TextAutosizingClusterInfo {
- explicit TextAutosizingClusterInfo(RenderBlock* root)
- : root(root)
- , blockContainingAllText(0)
- , maxAllowedDifferenceFromTextWidth(150)
+// Represents a POD of a selection of fields for hashing. The fields are selected to detect similar
+// nodes in the Render Tree from the viewpoint of text autosizing.
+struct RenderObjectPodForHash {
+ RenderObjectPodForHash()
+ : qualifiedNameHash(0)
+ , packedStyleProperties(0)
+ , width(0)
{
}
+ ~RenderObjectPodForHash() { }
- RenderBlock* root;
- const RenderBlock* blockContainingAllText;
+ unsigned qualifiedNameHash;
- // Upper limit on the difference between the width of the cluster's block containing all
- // text and that of a narrow child before the child becomes a separate cluster.
- float maxAllowedDifferenceFromTextWidth;
-
- // Descendants of the cluster that are narrower than the block containing all text and must be
- // processed together.
- Vector<TextAutosizingClusterInfo> narrowDescendants;
+ // Style specific selection of signals
+ unsigned packedStyleProperties;
+ float width;
};
+// To allow for efficient hashing using StringHasher.
+COMPILE_ASSERT(!(sizeof(RenderObjectPodForHash) % sizeof(UChar)), RenderObjectPodForHashMultipleOfUchar);
#ifdef AUTOSIZING_DOM_DEBUG_INFO
static void writeDebugInfo(RenderObject* renderObject, const AtomicString& output)
@@ -104,48 +106,115 @@ static RenderObject* getAncestorList(const RenderObject* renderer)
// see http://www.whatwg.org/specs/web-apps/current-work/multipage/grouping-content.html#the-li-element
for (RenderObject* ancestor = renderer->parent(); ancestor; ancestor = ancestor->parent()) {
Node* parentNode = ancestor->generatingNode();
- if (parentNode && (parentNode->hasTagName(olTag) || parentNode->hasTagName(ulTag)))
+ if (parentNode && (isHTMLOListElement(*parentNode) || isHTMLUListElement(*parentNode)))
return ancestor;
}
return 0;
}
+static Node* getGeneratingElementNode(const RenderObject* renderer)
+{
+ Node* node = renderer->generatingNode();
+ return (node && node->isElementNode()) ? node : 0;
+}
+
+static unsigned hashMemory(const void* data, size_t length)
+{
+ return StringHasher::computeHash<UChar>(static_cast<const UChar*>(data), length / sizeof(UChar));
+}
+
+static unsigned computeLocalHash(const RenderObject* renderer)
+{
+ Node* generatingElementNode = getGeneratingElementNode(renderer);
+ ASSERT(generatingElementNode);
+
+ RenderObjectPodForHash podForHash;
+ podForHash.qualifiedNameHash = QualifiedNameHash::hash(toElement(generatingElementNode)->tagQName());
+
+ if (RenderStyle* style = renderer->style()) {
+ podForHash.packedStyleProperties = style->direction();
+ podForHash.packedStyleProperties |= (style->position() << 1);
+ podForHash.packedStyleProperties |= (style->floating() << 4);
+ podForHash.packedStyleProperties |= (style->display() << 6);
+ podForHash.packedStyleProperties |= (style->width().type() << 11);
+ // packedStyleProperties effectively using 15 bits now.
+
+ // consider for adding: writing mode, padding.
+
+ podForHash.width = style->width().getFloatValue();
+ }
+
+ return hashMemory(&podForHash, sizeof(podForHash));
+}
+
TextAutosizer::TextAutosizer(Document* document)
: m_document(document)
+ , m_previouslyAutosized(false)
+{
+}
+
+unsigned TextAutosizer::getCachedHash(const RenderObject* renderer, bool putInCacheIfAbsent)
{
+ HashMap<const RenderObject*, unsigned>::const_iterator it = m_hashCache.find(renderer);
+ if (it != m_hashCache.end())
+ return it->value;
+
+ RenderObject* rendererParent = renderer->parent();
+ while (rendererParent && !getGeneratingElementNode(rendererParent))
+ rendererParent = rendererParent->parent();
+
+ const unsigned parentHashValue = rendererParent ? getCachedHash(rendererParent, true) : 0;
+ const unsigned hashes[2] = { parentHashValue, computeLocalHash(renderer) };
+ const unsigned combinedHashValue = hashMemory(hashes, sizeof(hashes));
+ if (putInCacheIfAbsent)
+ m_hashCache.add(renderer, combinedHashValue);
+ return combinedHashValue;
+}
+
+bool TextAutosizer::isApplicable() const
+{
+ return m_document->settings()
+ && m_document->settings()->textAutosizingEnabled()
+ && m_document->page()
+ && m_document->page()->mainFrame()
+ && m_document->page()->deprecatedLocalMainFrame()->loader().stateMachine()->committedFirstRealDocumentLoad();
}
void TextAutosizer::recalculateMultipliers()
{
- RenderObject* renderer = m_document->renderer();
+ if (!isApplicable() && !m_previouslyAutosized)
+ return;
+
+ RenderObject* renderer = m_document->renderView();
while (renderer) {
if (renderer->style() && renderer->style()->textAutosizingMultiplier() != 1)
setMultiplier(renderer, 1);
renderer = renderer->nextInPreOrder();
}
+ m_previouslyAutosized = false;
}
bool TextAutosizer::processSubtree(RenderObject* layoutRoot)
{
- TRACE_EVENT0("webkit", "TextAutosizer::processSubtree");
+ TRACE_EVENT0("webkit", "TextAutosizer: check if needed");
- if (!m_document->settings() || !m_document->settings()->textAutosizingEnabled() || layoutRoot->view()->document().printing() || !m_document->page())
+ if (!isApplicable() || layoutRoot->view()->document().printing())
return false;
- Frame* mainFrame = m_document->page()->mainFrame();
-
+ LocalFrame* mainFrame = m_document->page()->deprecatedLocalMainFrame();
TextAutosizingWindowInfo windowInfo;
// Window area, in logical (density-independent) pixels.
windowInfo.windowSize = m_document->settings()->textAutosizingWindowSizeOverride();
if (windowInfo.windowSize.isEmpty())
- windowInfo.windowSize = mainFrame->view()->unscaledVisibleContentSize(ScrollableArea::IncludeScrollbars);
+ windowInfo.windowSize = mainFrame->view()->unscaledVisibleContentSize(IncludeScrollbars);
// Largest area of block that can be visible at once (assuming the main
// frame doesn't get scaled to less than overview scale), in CSS pixels.
windowInfo.minLayoutSize = mainFrame->view()->layoutSize();
- for (Frame* frame = m_document->frame(); frame; frame = frame->tree().parent())
- windowInfo.minLayoutSize = windowInfo.minLayoutSize.shrunkTo(frame->view()->layoutSize());
+ for (Frame* frame = m_document->frame(); frame; frame = frame->tree().parent()) {
+ windowInfo.minLayoutSize = windowInfo.minLayoutSize.shrunkTo(toLocalFrame(frame)->view()->layoutSize());
+ }
// The layoutRoot could be neither a container nor a cluster, so walk up the tree till we find each of these.
RenderBlock* container = layoutRoot->isRenderBlock() ? toRenderBlock(layoutRoot) : layoutRoot->containingBlock();
@@ -163,9 +232,21 @@ bool TextAutosizer::processSubtree(RenderObject* layoutRoot)
std::numeric_limits<float>::infinity()) == 1.0f)
return false;
+ TRACE_EVENT0("webkit", "TextAutosizer: process root cluster");
+ UseCounter::count(*m_document, UseCounter::TextAutosizing);
+
TextAutosizingClusterInfo clusterInfo(cluster);
processCluster(clusterInfo, container, layoutRoot, windowInfo);
- InspectorInstrumentation::didAutosizeText(layoutRoot);
+
+#ifdef AUTOSIZING_CLUSTER_HASH
+ // Second pass to autosize stale non-autosized clusters for consistency.
+ secondPassProcessStaleNonAutosizedClusters();
+ m_hashCache.clear();
+ m_hashToMultiplier.clear();
+ m_hashesToAutosizeSecondPass.clear();
+ m_nonAutosizedClusters.clear();
+#endif
+ m_previouslyAutosized = true;
return true;
}
@@ -180,9 +261,10 @@ float TextAutosizer::clusterMultiplier(WritingMode writingMode, const TextAutosi
multiplier *= m_document->settings()->accessibilityFontScaleFactor();
// If the page has a meta viewport or @viewport, don't apply the device scale adjustment.
- const ViewportDescription& viewportDescription = m_document->page()->mainFrame()->document()->viewportDescription();
+ const ViewportDescription& viewportDescription = m_document->page()->deprecatedLocalMainFrame()->document()->viewportDescription();
if (!viewportDescription.isSpecifiedByAuthor()) {
- multiplier *= m_document->settings()->deviceScaleAdjustment();
+ float deviceScaleAdjustment = m_document->settings()->deviceScaleAdjustment();
+ multiplier *= deviceScaleAdjustment;
}
return std::max(1.0f, multiplier);
}
@@ -191,7 +273,7 @@ void TextAutosizer::processClusterInternal(TextAutosizingClusterInfo& clusterInf
{
processContainer(multiplier, container, clusterInfo, subtreeRoot, windowInfo);
#ifdef AUTOSIZING_DOM_DEBUG_INFO
- writeDebugInfo(clusterInfo.root, String::format("cluster:%f", multiplier));
+ writeDebugInfo(clusterInfo.root, AtomicString(String::format("cluster:%f", multiplier)));
#endif
Vector<Vector<TextAutosizingClusterInfo> > narrowDescendantsGroups;
@@ -200,6 +282,58 @@ void TextAutosizer::processClusterInternal(TextAutosizingClusterInfo& clusterInf
processCompositeCluster(narrowDescendantsGroups[i], windowInfo);
}
+unsigned TextAutosizer::computeCompositeClusterHash(Vector<TextAutosizingClusterInfo>& clusterInfos)
+{
+ if (clusterInfos.size() == 1 && getGeneratingElementNode(clusterInfos[0].root))
+ return getCachedHash(clusterInfos[0].root, false);
+
+ // FIXME: consider hashing clusters for which clusterInfos.size() > 1
+ return 0;
+}
+
+void TextAutosizer::addNonAutosizedCluster(unsigned key, TextAutosizingClusterInfo& value)
+{
+ HashMap<unsigned, OwnPtr<Vector<TextAutosizingClusterInfo> > >::const_iterator it = m_nonAutosizedClusters.find(key);
+ if (it == m_nonAutosizedClusters.end()) {
+ m_nonAutosizedClusters.add(key, adoptPtr(new Vector<TextAutosizingClusterInfo>(1, value)));
+ return;
+ }
+ it->value->append(value);
+}
+
+float TextAutosizer::computeMultiplier(Vector<TextAutosizingClusterInfo>& clusterInfos, const TextAutosizingWindowInfo& windowInfo, float textWidth)
+{
+#ifdef AUTOSIZING_CLUSTER_HASH
+ // When hashing is enabled this function returns a multiplier based on previously seen clusters.
+ // It will return a non-unit multiplier if a cluster with the same hash value has been previously
+ // autosized.
+ unsigned clusterHash = computeCompositeClusterHash(clusterInfos);
+#else
+ unsigned clusterHash = 0;
+#endif
+
+ if (clusterHash) {
+ HashMap<unsigned, float>::iterator it = m_hashToMultiplier.find(clusterHash);
+ if (it != m_hashToMultiplier.end())
+ return it->value;
+ }
+
+ if (compositeClusterShouldBeAutosized(clusterInfos, textWidth)) {
+ float multiplier = clusterMultiplier(clusterInfos[0].root->style()->writingMode(), windowInfo, textWidth);
+ if (clusterHash) {
+ if (multiplier > 1 && m_nonAutosizedClusters.contains(clusterHash))
+ m_hashesToAutosizeSecondPass.append(clusterHash);
+ m_hashToMultiplier.add(clusterHash, multiplier);
+ }
+ return multiplier;
+ }
+
+ if (clusterHash)
+ addNonAutosizedCluster(clusterHash, clusterInfos[0]);
+
+ return 1.0f;
+}
+
void TextAutosizer::processCluster(TextAutosizingClusterInfo& clusterInfo, RenderBlock* container, RenderObject* subtreeRoot, const TextAutosizingWindowInfo& windowInfo)
{
// Many pages set a max-width on their content. So especially for the RenderView, instead of
@@ -207,10 +341,11 @@ void TextAutosizer::processCluster(TextAutosizingClusterInfo& clusterInfo, Rende
// descendant text node of the cluster (i.e. the deepest wrapper block that contains all the
// text), and use its width instead.
clusterInfo.blockContainingAllText = findDeepestBlockContainingAllText(clusterInfo.root);
- float textWidth = clusterInfo.blockContainingAllText->contentLogicalWidth();
- float multiplier = 1.0;
- if (clusterShouldBeAutosized(clusterInfo, textWidth))
- multiplier = clusterMultiplier(clusterInfo.root->style()->writingMode(), windowInfo, textWidth);
+ float textWidth = clusterInfo.blockContainingAllText->contentLogicalWidth().toFloat();
+
+ Vector<TextAutosizingClusterInfo> clusterInfos(1, clusterInfo);
+ float multiplier = computeMultiplier(clusterInfos, windowInfo, textWidth);
+
processClusterInternal(clusterInfo, container, subtreeRoot, windowInfo, multiplier);
}
@@ -223,18 +358,52 @@ void TextAutosizer::processCompositeCluster(Vector<TextAutosizingClusterInfo>& c
for (size_t i = 0; i < clusterInfos.size(); ++i) {
TextAutosizingClusterInfo& clusterInfo = clusterInfos[i];
clusterInfo.blockContainingAllText = findDeepestBlockContainingAllText(clusterInfo.root);
- maxTextWidth = max<float>(maxTextWidth, clusterInfo.blockContainingAllText->contentLogicalWidth());
+ maxTextWidth = max<float>(maxTextWidth, clusterInfo.blockContainingAllText->contentLogicalWidth().toFloat());
}
- float multiplier = 1.0;
- if (compositeClusterShouldBeAutosized(clusterInfos, maxTextWidth))
- multiplier = clusterMultiplier(clusterInfos[0].root->style()->writingMode(), windowInfo, maxTextWidth);
+ float multiplier = computeMultiplier(clusterInfos, windowInfo, maxTextWidth);
for (size_t i = 0; i < clusterInfos.size(); ++i) {
ASSERT(clusterInfos[i].root->style()->writingMode() == clusterInfos[0].root->style()->writingMode());
processClusterInternal(clusterInfos[i], clusterInfos[i].root, clusterInfos[i].root, windowInfo, multiplier);
}
}
+void TextAutosizer::secondPassProcessStaleNonAutosizedClusters()
+{
+ for (size_t i = 0; i < m_hashesToAutosizeSecondPass.size(); ++i) {
+ unsigned hash = m_hashesToAutosizeSecondPass[i];
+ float multiplier = m_hashToMultiplier.get(hash);
+ Vector<TextAutosizingClusterInfo>* val = m_nonAutosizedClusters.get(hash);
+ for (Vector<TextAutosizingClusterInfo>::iterator it2 = val->begin(); it2 != val->end(); ++it2)
+ processStaleContainer(multiplier, (*it2).root, *it2);
+ }
+}
+
+void TextAutosizer::processStaleContainer(float multiplier, RenderBlock* cluster, TextAutosizingClusterInfo& clusterInfo)
+{
+ ASSERT(isAutosizingContainer(cluster));
+
+ // This method is different from processContainer() mainly in that it does not recurse into sub-clusters.
+ // Multiplier updates are restricted to the specified cluster only. Also the multiplier > 1 by construction
+ // of m_hashesToAutosizeSecondPass, so we don't need to check it explicitly.
+ float localMultiplier = containerShouldBeAutosized(cluster) ? multiplier : 1;
+
+ RenderObject* descendant = nextInPreOrderSkippingDescendantsOfContainers(cluster, cluster);
+ while (descendant) {
+ if (descendant->isText()) {
+ if (localMultiplier != 1 && descendant->style()->textAutosizingMultiplier() == 1) {
+ setMultiplier(descendant, localMultiplier);
+ setMultiplier(descendant->parent(), localMultiplier); // Parent does line spacing.
+ }
+ } else if (isAutosizingContainer(descendant)) {
+ RenderBlock* descendantBlock = toRenderBlock(descendant);
+ if (!isAutosizingCluster(descendantBlock, clusterInfo))
+ processStaleContainer(multiplier, descendantBlock, clusterInfo);
+ }
+ descendant = nextInPreOrderSkippingDescendantsOfContainers(descendant, cluster);
+ }
+}
+
void TextAutosizer::processContainer(float multiplier, RenderBlock* container, TextAutosizingClusterInfo& clusterInfo, RenderObject* subtreeRoot, const TextAutosizingWindowInfo& windowInfo)
{
ASSERT(isAutosizingContainer(container));
@@ -242,7 +411,7 @@ void TextAutosizer::processContainer(float multiplier, RenderBlock* container, T
writeDebugInfo(container, "container");
#endif
- float localMultiplier = containerShouldBeAutosized(container) ? multiplier: 1;
+ float localMultiplier = (multiplier > 1 && containerShouldBeAutosized(container)) ? multiplier: 1;
RenderObject* descendant = nextInPreOrderSkippingDescendantsOfContainers(subtreeRoot, subtreeRoot);
while (descendant) {
@@ -287,12 +456,12 @@ void TextAutosizer::setMultiplierForList(RenderObject* renderer, float multiplie
#ifndef NDEBUG
Node* parentNode = renderer->generatingNode();
ASSERT(parentNode);
- ASSERT(parentNode->hasTagName(olTag) || parentNode->hasTagName(ulTag));
+ ASSERT(isHTMLOListElement(parentNode) || isHTMLUListElement(parentNode));
#endif
setMultiplier(renderer, multiplier);
// Make sure all list items are autosized consistently.
- for (RenderObject* child = renderer->firstChild(); child; child = child->nextSibling()) {
+ for (RenderObject* child = renderer->slowFirstChild(); child; child = child->nextSibling()) {
if (child->isListItem() && child->style()->textAutosizingMultiplier() == 1)
setMultiplier(child, multiplier);
}
@@ -337,7 +506,7 @@ bool TextAutosizer::isAutosizingContainer(const RenderObject* renderer)
// - Must not be normal list items, as items in the same list should look
// consistent, unless they are floating or position:absolute/fixed.
Node* node = renderer->generatingNode();
- if ((node && !node->hasChildNodes())
+ if ((node && !node->hasChildren())
|| !renderer->isRenderBlock()
|| (renderer->isInline() && !renderer->style()->isDisplayReplacedType()))
return false;
@@ -367,14 +536,14 @@ bool TextAutosizer::isNarrowDescendant(const RenderBlock* renderer, TextAutosizi
// the enclosing cluster. This 150px limit is adjusted whenever a descendant container is
// less than 50px narrower than the current limit.
const float differenceFromMaxWidthDifference = 50;
- float contentWidth = renderer->contentLogicalWidth();
- float clusterTextWidth = parentClusterInfo.blockContainingAllText->contentLogicalWidth();
- float widthDifference = clusterTextWidth - contentWidth;
+ LayoutUnit contentWidth = renderer->contentLogicalWidth();
+ LayoutUnit clusterTextWidth = parentClusterInfo.blockContainingAllText->contentLogicalWidth();
+ LayoutUnit widthDifference = clusterTextWidth - contentWidth;
if (widthDifference - parentClusterInfo.maxAllowedDifferenceFromTextWidth > differenceFromMaxWidthDifference)
return true;
- parentClusterInfo.maxAllowedDifferenceFromTextWidth = std::max(widthDifference, parentClusterInfo.maxAllowedDifferenceFromTextWidth);
+ parentClusterInfo.maxAllowedDifferenceFromTextWidth = std::max(widthDifference.toFloat(), parentClusterInfo.maxAllowedDifferenceFromTextWidth);
return false;
}
@@ -384,8 +553,8 @@ bool TextAutosizer::isWiderDescendant(const RenderBlock* renderer, const TextAut
// Autosizing containers that are wider than the |blockContainingAllText| of their enclosing
// cluster are treated the same way as autosizing clusters to be autosized separately.
- float contentWidth = renderer->contentLogicalWidth();
- float clusterTextWidth = parentClusterInfo.blockContainingAllText->contentLogicalWidth();
+ LayoutUnit contentWidth = renderer->contentLogicalWidth();
+ LayoutUnit clusterTextWidth = parentClusterInfo.blockContainingAllText->contentLogicalWidth();
return contentWidth > clusterTextWidth;
}
@@ -412,6 +581,7 @@ bool TextAutosizer::isIndependentDescendant(const RenderBlock* renderer)
// from the box's parent (we want to avoid having significantly different
// width blocks within a cluster, since the narrower blocks would end up
// larger than would otherwise be necessary).
+ RenderBlock* containingBlock = renderer->containingBlock();
return renderer->isRenderView()
|| renderer->isFloating()
|| renderer->isOutOfFlowPositioned()
@@ -419,7 +589,7 @@ bool TextAutosizer::isIndependentDescendant(const RenderBlock* renderer)
|| renderer->isTableCaption()
|| renderer->isFlexibleBoxIncludingDeprecated()
|| renderer->hasColumns()
- || renderer->containingBlock()->isHorizontalWritingMode() != renderer->isHorizontalWritingMode()
+ || (containingBlock && containingBlock->isHorizontalWritingMode() != renderer->isHorizontalWritingMode())
|| renderer->style()->isDisplayReplacedType()
|| renderer->isTextArea()
|| renderer->style()->userModify() != READ_ONLY;
@@ -520,7 +690,7 @@ bool TextAutosizer::contentHeightIsConstrained(const RenderBlock* container)
if (style->height().isSpecified() || style->maxHeight().isSpecified() || container->isOutOfFlowPositioned()) {
// Some sites (e.g. wikipedia) set their html and/or body elements to height:100%,
// without intending to constrain the height of the content within them.
- return !container->isRoot() && !container->isBody();
+ return !container->isDocumentElement() && !container->isBody();
}
if (container->isFloating())
return false;
@@ -528,12 +698,6 @@ bool TextAutosizer::contentHeightIsConstrained(const RenderBlock* container)
return false;
}
-bool TextAutosizer::clusterShouldBeAutosized(TextAutosizingClusterInfo& clusterInfo, float blockWidth)
-{
- Vector<TextAutosizingClusterInfo> clusterInfos(1, clusterInfo);
- return compositeClusterShouldBeAutosized(clusterInfos, blockWidth);
-}
-
bool TextAutosizer::compositeClusterShouldBeAutosized(Vector<TextAutosizingClusterInfo>& clusterInfos, float blockWidth)
{
// Don't autosize clusters that contain less than 4 lines of text (in
@@ -634,11 +798,11 @@ const RenderBlock* TextAutosizer::findDeepestBlockContainingAllText(const Render
const RenderObject* TextAutosizer::findFirstTextLeafNotInCluster(const RenderObject* parent, size_t& depth, TraversalDirection direction)
{
- if (parent->isEmpty())
- return parent->isText() ? parent : 0;
+ if (parent->isText())
+ return parent;
++depth;
- const RenderObject* child = (direction == FirstToLast) ? parent->firstChild() : parent->lastChild();
+ const RenderObject* child = (direction == FirstToLast) ? parent->slowFirstChild() : parent->slowLastChild();
while (child) {
if (!isAutosizingContainer(child) || !isIndependentDescendant(toRenderBlock(child))) {
const RenderObject* leaf = findFirstTextLeafNotInCluster(child, depth, direction);
@@ -681,8 +845,8 @@ void TextAutosizer::getNarrowDescendantsGroupedByWidth(const TextAutosizingClust
groups.last().append(clusterInfos[i]);
if (i + 1 < clusterInfos.size()) {
- float currentWidth = clusterInfos[i].root->contentLogicalWidth();
- float nextWidth = clusterInfos[i + 1].root->contentLogicalWidth();
+ LayoutUnit currentWidth = clusterInfos[i].root->contentLogicalWidth();
+ LayoutUnit nextWidth = clusterInfos[i + 1].root->contentLogicalWidth();
if (currentWidth - nextWidth > maxWidthDifferenceWithinGroup)
groups.grow(groups.size() + 1);
}