Index: Source/core/rendering/FastTextAutosizer.cpp |
diff --git a/Source/core/rendering/FastTextAutosizer.cpp b/Source/core/rendering/FastTextAutosizer.cpp |
index 3f0f5573fecb952b4728169817acdf3908740cdd..b78ade35f56f76f09015361ce9402db3f1f151a2 100644 |
--- a/Source/core/rendering/FastTextAutosizer.cpp |
+++ b/Source/core/rendering/FastTextAutosizer.cpp |
@@ -234,10 +234,10 @@ FastTextAutosizer::FastTextAutosizer(const Document* document) |
, m_frameWidth(0) |
, m_layoutWidth(0) |
, m_baseMultiplier(0) |
- , m_pageAutosizingStatus(PageAutosizingStatusUnknown) |
+ , m_pageNeedsAutosizing(false) |
+ , m_previouslyAutosized(false) |
, m_firstBlock(0) |
#ifndef NDEBUG |
- , m_renderViewInfoPrepared(false) |
, m_blocksThatHaveBegunLayout() |
#endif |
, m_superclusters() |
@@ -290,7 +290,7 @@ void FastTextAutosizer::prepareClusterStack(const RenderObject* renderer) |
void FastTextAutosizer::beginLayout(RenderBlock* block) |
{ |
- ASSERT(enabled() && m_pageAutosizingStatus == PageNeedsAutosizing); |
+ ASSERT(enabled() && m_pageNeedsAutosizing); |
#ifndef NDEBUG |
m_blocksThatHaveBegunLayout.add(block); |
#endif |
@@ -316,7 +316,7 @@ void FastTextAutosizer::beginLayout(RenderBlock* block) |
void FastTextAutosizer::inflateListItem(RenderListItem* listItem, RenderListMarker* listItemMarker) |
{ |
- if (!enabled() || m_pageAutosizingStatus != PageNeedsAutosizing) |
+ if (!enabled() || !m_pageNeedsAutosizing) |
return; |
ASSERT(listItem && listItemMarker); |
#ifndef NDEBUG |
@@ -379,11 +379,10 @@ void FastTextAutosizer::inflateTable(RenderTable* table) |
void FastTextAutosizer::endLayout(RenderBlock* block) |
{ |
- ASSERT(enabled() && m_pageAutosizingStatus == PageNeedsAutosizing); |
+ ASSERT(enabled() && m_pageNeedsAutosizing); |
if (block == m_firstBlock) { |
m_firstBlock = 0; |
- m_pageAutosizingStatus = PageAutosizingStatusUnknown; |
m_clusterStack.clear(); |
m_superclusters.clear(); |
#ifndef NDEBUG |
@@ -425,8 +424,28 @@ bool FastTextAutosizer::enabled() |
return m_document->settings()->textAutosizingEnabled(); |
} |
-void FastTextAutosizer::updateRenderViewInfo() |
+void FastTextAutosizer::updatePageInfoInAllFrames() |
{ |
+ if (!enabled()) |
+ return; |
+ |
+ ASSERT(m_document->frame()->isMainFrame()); |
+ |
+ for (LocalFrame* frame = m_document->frame(); frame; frame = frame->tree().traverseNext()) { |
+ if (FastTextAutosizer* textAutosizer = frame->document()->fastTextAutosizer()) |
+ textAutosizer->updatePageInfo(); |
+ } |
+} |
+ |
+void FastTextAutosizer::updatePageInfo() |
+{ |
+ if (!enabled()) |
+ return; |
+ |
+ int previousFrameWidth = m_frameWidth; |
+ int previousLayoutWidth = m_layoutWidth; |
+ float previousBaseMultiplier = m_baseMultiplier; |
+ |
RenderView* renderView = toRenderView(m_document->renderer()); |
bool horizontalWritingMode = isHorizontalWritingMode(renderView->style()->writingMode()); |
@@ -448,12 +467,43 @@ void FastTextAutosizer::updateRenderViewInfo() |
m_baseMultiplier *= deviceScaleAdjustment; |
} |
- m_pageAutosizingStatus = m_frameWidth && (m_baseMultiplier * (static_cast<float>(m_layoutWidth) / m_frameWidth) > 1.0f) |
- ? PageNeedsAutosizing : PageDoesNotNeedAutosizing; |
+ m_pageNeedsAutosizing = !!m_frameWidth |
+ && (m_baseMultiplier * (static_cast<float>(m_layoutWidth) / m_frameWidth) > 1.0f); |
-#ifndef NDEBUG |
- m_renderViewInfoPrepared = true; |
-#endif |
+ // If we are no longer autosizing the page, we won't do anything during the next layout. |
+ // Set all the multipliers back to 1 now. |
+ if (!m_pageNeedsAutosizing && m_previouslyAutosized) |
+ resetMultipliers(); |
+ |
+ // If page info has changed, multipliers may have changed. Force a layout to recompute them. |
+ if (m_pageNeedsAutosizing |
+ && (m_frameWidth != previousFrameWidth |
+ || m_layoutWidth != previousLayoutWidth |
+ || m_baseMultiplier != previousBaseMultiplier)) |
+ setAllTextNeedsLayout(); |
+} |
+ |
+void FastTextAutosizer::resetMultipliers() |
+{ |
+ RenderObject* renderer = m_document->renderer(); |
+ while (renderer) { |
+ if (RenderStyle* style = renderer->style()) { |
+ if (style->textAutosizingMultiplier() != 1) |
+ applyMultiplier(renderer, 1, LayoutNeeded); |
+ } |
+ renderer = renderer->nextInPreOrder(); |
+ } |
+ m_previouslyAutosized = false; |
+} |
+ |
+void FastTextAutosizer::setAllTextNeedsLayout() |
+{ |
+ RenderObject* renderer = m_document->renderer(); |
+ while (renderer) { |
+ if (renderer->isText()) |
+ renderer->setNeedsLayout(); |
+ renderer = renderer->nextInPreOrder(); |
+ } |
} |
bool FastTextAutosizer::clusterWouldHaveEnoughTextToAutosize(const RenderBlock* root, const RenderBlock* widthProvider) |
@@ -621,7 +671,6 @@ const RenderBlock* FastTextAutosizer::deepestCommonAncestor(BlockSet& blocks) |
float FastTextAutosizer::clusterMultiplier(Cluster* cluster) |
{ |
- ASSERT(m_renderViewInfoPrepared); |
if (!cluster->m_multiplier) { |
if (cluster->m_root->isTable() |
|| isIndependentDescendant(cluster->m_root) |
@@ -790,7 +839,7 @@ const RenderObject* FastTextAutosizer::findTextLeaf(const RenderObject* parent, |
return 0; |
} |
-void FastTextAutosizer::applyMultiplier(RenderObject* renderer, float multiplier) |
+void FastTextAutosizer::applyMultiplier(RenderObject* renderer, float multiplier, RelayoutBehavior relayoutBehavior) |
{ |
ASSERT(renderer); |
RenderStyle* currentStyle = renderer->style(); |
@@ -801,7 +850,21 @@ void FastTextAutosizer::applyMultiplier(RenderObject* renderer, float multiplier |
RefPtr<RenderStyle> style = RenderStyle::clone(currentStyle); |
style->setTextAutosizingMultiplier(multiplier); |
style->setUnique(); |
- renderer->setStyleInternal(style.release()); |
+ |
+ switch (relayoutBehavior) { |
+ case AlreadyInLayout: |
+ renderer->setStyleInternal(style.release()); |
+ if (renderer->isRenderBlock()) |
+ toRenderBlock(renderer)->invalidateLineHeight(); |
+ break; |
+ |
+ case LayoutNeeded: |
+ renderer->setStyle(style.release()); |
+ break; |
+ } |
+ |
+ if (multiplier != 1) |
+ m_previouslyAutosized = true; |
} |
bool FastTextAutosizer::isWiderOrNarrowerDescendant(Cluster* cluster) |
@@ -912,15 +975,7 @@ FastTextAutosizer::LayoutScope::LayoutScope(RenderBlock* block) |
if (!m_textAutosizer) |
return; |
- if (!m_textAutosizer->enabled()) { |
- m_textAutosizer = 0; |
- return; |
- } |
- |
- if (m_textAutosizer->m_pageAutosizingStatus == PageAutosizingStatusUnknown) |
- m_textAutosizer->updateRenderViewInfo(); |
- |
- if (m_textAutosizer->m_pageAutosizingStatus == PageNeedsAutosizing) |
+ if (m_textAutosizer->enabled() && m_textAutosizer->m_pageNeedsAutosizing) |
m_textAutosizer->beginLayout(m_block); |
else |
m_textAutosizer = 0; |