WebKit Bugzilla
Attachment 369753 Details for
Bug 197808
: Move idempotent text autosizing to StyleTreeResolver
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP
bug-197808-20190513113102.patch (text/plain), 19.26 KB, created by
Myles C. Maxfield
on 2019-05-13 11:31:03 PDT
(
hide
)
Description:
WIP
Filename:
MIME Type:
Creator:
Myles C. Maxfield
Created:
2019-05-13 11:31:03 PDT
Size:
19.26 KB
patch
obsolete
>Subversion Revision: 245209 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index c7c8dca14ce903e098d1f71e080a713200ad53f9..413cc14f0883dea350a1a80f4a7b4eda34e72ba5 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,29 @@ >+2019-05-11 Myles C. Maxfield <mmaxfield@apple.com> >+ >+ Move idempotent text autosizing to StyleTreeResolver >+ https://bugs.webkit.org/show_bug.cgi?id=197808 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ No new tests (OOPS!). >+ >+ * page/FrameViewLayoutContext.cpp: >+ (WebCore::FrameViewLayoutContext::applyTextSizingIfNeeded): >+ * rendering/RenderBlockFlow.cpp: >+ (WebCore::RenderBlockFlow::adjustComputedFontSizes): >+ (WebCore::idempotentTextSize): Deleted. >+ * rendering/RenderBlockFlow.h: >+ * rendering/RenderElement.cpp: >+ (WebCore::includeNonFixedHeight): >+ (WebCore::RenderElement::adjustComputedFontSizesOnBlocks): >+ (WebCore::RenderElement::resetTextAutosizing): >+ * style/StyleTreeResolver.cpp: >+ (WebCore::Style::AutosizeStatus::shouldSkipSubtree const): >+ (WebCore::Style::apply): >+ (WebCore::Style::TreeResolver::autosizeText): >+ (WebCore::Style::TreeResolver::resolve): >+ * style/StyleTreeResolver.h: >+ > 2019-05-11 Simon Fraser <simon.fraser@apple.com> > > Layer bounds are incorrect for sharing layers that paint with transforms >diff --git a/Source/WebCore/page/FrameViewLayoutContext.cpp b/Source/WebCore/page/FrameViewLayoutContext.cpp >index c61085c476383f0c4b3920b0d9b083475d411eff..47d66887121c0befd406d838a9ad74a632eb72c1 100644 >--- a/Source/WebCore/page/FrameViewLayoutContext.cpp >+++ b/Source/WebCore/page/FrameViewLayoutContext.cpp >@@ -491,16 +491,15 @@ bool FrameViewLayoutContext::canPerformLayout() const > void FrameViewLayoutContext::applyTextSizingIfNeeded(RenderElement& layoutRoot) > { > auto& settings = layoutRoot.settings(); >- if (!settings.textAutosizingEnabled() || renderView()->printing()) >+ if (!settings.textAutosizingEnabled() || settings.textAutosizingUsesIdempotentMode() || renderView()->printing()) > return; >- bool idempotentMode = settings.textAutosizingUsesIdempotentMode(); > auto minimumZoomFontSize = settings.minimumZoomFontSize(); >- if (!idempotentMode && !minimumZoomFontSize) >+ if (!minimumZoomFontSize) > return; > auto textAutosizingWidth = layoutRoot.page().textAutosizingWidth(); > if (auto overrideWidth = settings.textAutosizingWindowSizeOverride().width()) > textAutosizingWidth = overrideWidth; >- if (!idempotentMode && !textAutosizingWidth) >+ if (!textAutosizingWidth) > return; > layoutRoot.adjustComputedFontSizesOnBlocks(minimumZoomFontSize, textAutosizingWidth); > if (!layoutRoot.needsLayout()) >diff --git a/Source/WebCore/rendering/RenderBlockFlow.cpp b/Source/WebCore/rendering/RenderBlockFlow.cpp >index 766591cc9fecaa23e56374524c81f75c79097510..bc85c704459e66d3f46ac2b2172e5374d3a7f462 100644 >--- a/Source/WebCore/rendering/RenderBlockFlow.cpp >+++ b/Source/WebCore/rendering/RenderBlockFlow.cpp >@@ -3723,44 +3723,12 @@ static inline float textMultiplier(RenderObject& renderer, float specifiedSize) > return std::max((1.0f / log10f(specifiedSize) * coefficient), 1.0f); > } > >-static inline float idempotentTextSize(float specifiedSize, float pageScale) >-{ >- // This describes a piecewise curve when the page scale is 2/3. >- FloatPoint points[] = { {0.0f, 0.0f}, {6.0f, 12.0f}, {12.0f, 18.0f} }; >- >- // When the page scale is 1, the curve should be the identity. >- // Linearly interpolate between the curve above and identity based on the page scale. >- // Beware that depending on the specific values picked in the curve, this interpolation might change the shape of the curve for very small pageScales. >- pageScale = std::min(std::max(pageScale, 0.5f), 1.0f); >- auto scalePoint = [&](FloatPoint point) { >- float fraction = 3.0f - 3.0f * pageScale; >- point.setY(point.x() + (point.y() - point.x()) * fraction); >- return point; >- }; >- >- if (specifiedSize <= 0) >- return 0; >- >- float result = scalePoint(points[WTF_ARRAY_LENGTH(points) - 1]).y(); >- for (size_t i = 1; i < WTF_ARRAY_LENGTH(points); ++i) { >- if (points[i].x() < specifiedSize) >- continue; >- auto leftPoint = scalePoint(points[i - 1]); >- auto rightPoint = scalePoint(points[i]); >- float fraction = (specifiedSize - leftPoint.x()) / (rightPoint.x() - leftPoint.x()); >- result = leftPoint.y() + fraction * (rightPoint.y() - leftPoint.y()); >- break; >- } >- >- return std::max(result, specifiedSize); >-} >- >-void RenderBlockFlow::adjustComputedFontSizes(float size, float visibleWidth, float pageScale, bool idempotentMode) >+void RenderBlockFlow::adjustComputedFontSizes(float size, float visibleWidth) > { > LOG(TextAutosizing, "RenderBlockFlow %p adjustComputedFontSizes, size=%f visibleWidth=%f, width()=%f. Bailing: %d", this, size, visibleWidth, width().toFloat(), visibleWidth >= width()); > > // Don't do any work if the block is smaller than the visible area. >- if (!idempotentMode && visibleWidth >= width()) >+ if (visibleWidth >= width()) > return; > > unsigned lineCount; >@@ -3798,7 +3766,7 @@ void RenderBlockFlow::adjustComputedFontSizes(float size, float visibleWidth, fl > auto& fontDescription = oldStyle.fontDescription(); > float specifiedSize = fontDescription.specifiedSize(); > float scaledSize = roundf(specifiedSize * scale); >- if (idempotentMode || (scaledSize > 0 && scaledSize < minFontSize)) { >+ if (scaledSize > 0 && scaledSize < minFontSize) { > // Record the width of the block and the line count the first time we resize text and use it from then on for text resizing. > // This makes text resizing consistent even if the block's width or line count changes (which can be caused by text resizing itself 5159915). > if (m_lineCountForTextAutosizing == NOT_SET) >@@ -3806,14 +3774,8 @@ void RenderBlockFlow::adjustComputedFontSizes(float size, float visibleWidth, fl > if (m_widthForTextAutosizing == -1) > m_widthForTextAutosizing = actualWidth; > >- float candidateNewSize; >- if (idempotentMode) { >- float lineTextSize = idempotentTextSize(specifiedSize, pageScale); >- candidateNewSize = roundf(lineTextSize); >- } else { >- float lineTextMultiplier = lineCount == ONE_LINE ? oneLineTextMultiplier(text, specifiedSize) : textMultiplier(text, specifiedSize); >- candidateNewSize = roundf(std::min(minFontSize, specifiedSize * lineTextMultiplier)); >- } >+ float lineTextMultiplier = lineCount == ONE_LINE ? oneLineTextMultiplier(text, specifiedSize) : textMultiplier(text, specifiedSize); >+ float candidateNewSize = roundf(std::min(minFontSize, specifiedSize * lineTextMultiplier)); > > if (candidateNewSize > specifiedSize && candidateNewSize != fontDescription.computedSize() && text.textNode() && oldStyle.textSizeAdjust().isAuto()) > document().textAutoSizing().addTextNode(*text.textNode(), candidateNewSize); >diff --git a/Source/WebCore/rendering/RenderBlockFlow.h b/Source/WebCore/rendering/RenderBlockFlow.h >index c4ce223aec575476f44008c81a1ae7940619b78c..bdbbe3ceb5f7fb6450a16819ced5669ce13c7410 100644 >--- a/Source/WebCore/rendering/RenderBlockFlow.h >+++ b/Source/WebCore/rendering/RenderBlockFlow.h >@@ -604,7 +604,7 @@ public: > > #if ENABLE(TEXT_AUTOSIZING) > int lineCountForTextAutosizing(); >- void adjustComputedFontSizes(float size, float visibleWidth, float pageScale, bool idempotentMode); >+ void adjustComputedFontSizes(float size, float visibleWidth); > void resetComputedFontSize() > { > m_widthForTextAutosizing = -1; >diff --git a/Source/WebCore/rendering/RenderElement.cpp b/Source/WebCore/rendering/RenderElement.cpp >index 1a40fb268fa305408ec3b5c9f8c6aa2018fb88b1..a56124e569c8a098eac37f8cd6cb2b1e74afaa50 100644 >--- a/Source/WebCore/rendering/RenderElement.cpp >+++ b/Source/WebCore/rendering/RenderElement.cpp >@@ -2123,7 +2123,7 @@ static RenderObject::BlockContentHeightType includeNonFixedHeight(const RenderOb > } > return RenderObject::FixedHeight; > } >- if (renderer.document().settings().textAutosizingUsesIdempotentMode() && style.maxHeight().type() == Fixed && is<RenderBlock>(renderer) && style.maxHeight().value() <= downcast<RenderBlock>(renderer).layoutOverflowRect().maxY()) >+ if (style.maxHeight().type() == Fixed && is<RenderBlock>(renderer) && style.maxHeight().value() <= downcast<RenderBlock>(renderer).layoutOverflowRect().maxY()) > return RenderObject::FixedHeight; > return RenderObject::FlexibleHeight; > } >@@ -2134,12 +2134,9 @@ void RenderElement::adjustComputedFontSizesOnBlocks(float size, float visibleWid > if (!document) > return; > >- auto pageScale = document->page() ? document->page()->initialScale() : 1.0f; >- > Vector<int> depthStack; > int currentDepth = 0; > int newFixedDepth = 0; >- auto idempotentMode = document->settings().textAutosizingUsesIdempotentMode(); > > // We don't apply autosizing to nodes with fixed height normally. > // But we apply it to nodes which are located deep enough >@@ -2152,8 +2149,8 @@ void RenderElement::adjustComputedFontSizesOnBlocks(float size, float visibleWid > depthStack.append(newFixedDepth); > > int stackSize = depthStack.size(); >- if (is<RenderBlockFlow>(*descendent) && !descendent->isListItem() && (idempotentMode || !stackSize || currentDepth - depthStack[stackSize - 1] > TextAutoSizingFixedHeightDepth)) >- downcast<RenderBlockFlow>(*descendent).adjustComputedFontSizes(size, visibleWidth, pageScale, idempotentMode); >+ if (is<RenderBlockFlow>(*descendent) && !descendent->isListItem() && (!stackSize || currentDepth - depthStack[stackSize - 1] > TextAutoSizingFixedHeightDepth)) >+ downcast<RenderBlockFlow>(*descendent).adjustComputedFontSizes(size, visibleWidth); > newFixedDepth = 0; > } > >@@ -2174,7 +2171,6 @@ void RenderElement::resetTextAutosizing() > Vector<int> depthStack; > int currentDepth = 0; > int newFixedDepth = 0; >- auto idempotentMode = document->settings().textAutosizingUsesIdempotentMode(); > > for (RenderObject* descendent = traverseNext(this, includeNonFixedHeight, currentDepth, newFixedDepth); descendent; descendent = descendent->traverseNext(this, includeNonFixedHeight, currentDepth, newFixedDepth)) { > while (depthStack.size() > 0 && currentDepth <= depthStack[depthStack.size() - 1]) >@@ -2183,7 +2179,7 @@ void RenderElement::resetTextAutosizing() > depthStack.append(newFixedDepth); > > int stackSize = depthStack.size(); >- if (is<RenderBlockFlow>(*descendent) && !descendent->isListItem() && (idempotentMode || !stackSize || currentDepth - depthStack[stackSize - 1] > TextAutoSizingFixedHeightDepth)) >+ if (is<RenderBlockFlow>(*descendent) && !descendent->isListItem() && (!stackSize || currentDepth - depthStack[stackSize - 1] > TextAutoSizingFixedHeightDepth)) > downcast<RenderBlockFlow>(*descendent).resetComputedFontSize(); > newFixedDepth = 0; > } >diff --git a/Source/WebCore/style/StyleTreeResolver.cpp b/Source/WebCore/style/StyleTreeResolver.cpp >index 34edb5387d45d652527fad4ec881c5e0daed044c..a43b76ea03579425440e92d71017a34230cc5f98 100644 >--- a/Source/WebCore/style/StyleTreeResolver.cpp >+++ b/Source/WebCore/style/StyleTreeResolver.cpp >@@ -53,6 +53,7 @@ > #include "StyleResolver.h" > #include "StyleScope.h" > #include "Text.h" >+#include <wtf/HashSet.h> > > namespace WebCore { > >@@ -533,6 +534,170 @@ void TreeResolver::resolveComposedTree() > popParentsToDepth(1); > } > >+#if ENABLE(TEXT_AUTOSIZING) >+struct AutosizeStatus { >+ bool foundOutOfFlowPosition { false }; >+ bool foundFloat { false }; >+ bool foundInlineBlock { false }; >+ bool foundFixedHeight { false }; >+ bool foundDisplayNone { false }; >+ >+ bool shouldSkipSubtree() const >+ { >+ return foundOutOfFlowPosition || foundFloat || foundInlineBlock || foundFixedHeight || foundDisplayNone; >+ } >+}; >+ >+static AutosizeStatus apply(AutosizeStatus result, const RenderStyle* style) >+{ >+ if (!style) { >+ result.foundDisplayNone = true; >+ return result; >+ } >+ >+ if (style->hasOutOfFlowPosition()) >+ result.foundOutOfFlowPosition = true; >+ if (style->floating() != Float::No) >+ result.foundFloat = true; >+ switch (style->display()) { >+ case DisplayType::InlineBlock: >+ result.foundInlineBlock = true; >+ break; >+ case DisplayType::None: >+ result.foundDisplayNone = true; >+ break; >+ default: // FIXME: Add more cases. >+ break; >+ } >+ if (style->height().isFixed()) >+ result.foundFixedHeight = true; >+ return result; >+} >+ >+static inline float idempotentTextSize(float specifiedSize, float pageScale) >+{ >+ // This describes a piecewise curve when the page scale is 2/3. >+ FloatPoint points[] = { {0.0f, 0.0f}, {6.0f, 12.0f}, {12.0f, 18.0f} }; >+ >+ // When the page scale is 1, the curve should be the identity. >+ // Linearly interpolate between the curve above and identity based on the page scale. >+ // Beware that depending on the specific values picked in the curve, this interpolation might change the shape of the curve for very small pageScales. >+ pageScale = std::min(std::max(pageScale, 0.5f), 1.0f); >+ auto scalePoint = [&](FloatPoint point) { >+ float fraction = 3.0f - 3.0f * pageScale; >+ point.setY(point.x() + (point.y() - point.x()) * fraction); >+ return point; >+ }; >+ >+ if (specifiedSize <= 0) >+ return 0; >+ >+ float result = scalePoint(points[WTF_ARRAY_LENGTH(points) - 1]).y(); >+ for (size_t i = 1; i < WTF_ARRAY_LENGTH(points); ++i) { >+ if (points[i].x() < specifiedSize) >+ continue; >+ auto leftPoint = scalePoint(points[i - 1]); >+ auto rightPoint = scalePoint(points[i]); >+ float fraction = (specifiedSize - leftPoint.x()) / (rightPoint.x() - leftPoint.x()); >+ result = leftPoint.y() + fraction * (rightPoint.y() - leftPoint.y()); >+ break; >+ } >+ >+ return std::max(result, specifiedSize); >+} >+ >+static void modifyStyleForAutosizing(RenderStyle& style, float newTextSize, CSSFontSelector& fontSelector) >+{ >+ auto fontDescription = style.fontDescription(); >+ float specifiedSize = fontDescription.specifiedSize(); >+ fontDescription.setComputedSize(newTextSize); >+ >+ float scaleChange = newTextSize / specifiedSize; >+ auto& lineHeightLength = style.specifiedLineHeight(); >+ int specifiedLineHeight; >+ if (lineHeightLength.isPercent()) >+ specifiedLineHeight = minimumValueForLength(lineHeightLength, fontDescription.specifiedSize()); >+ else >+ specifiedLineHeight = lineHeightLength.value(); >+ >+ // This calculation matches the line-height computed size calculation in StyleBuilderCustom::applyValueLineHeight(). >+ int lineHeight = specifiedLineHeight * scaleChange; >+ if (!lineHeightLength.isFixed() || lineHeightLength.value() != lineHeight) { >+ style.setLineHeight(Length(lineHeight, Fixed)); >+ style.setSpecifiedLineHeight(Length { lineHeightLength }); >+ } >+ >+ style.setFontDescription(FontCascadeDescription { fontDescription }); >+ style.fontCascade().update(&fontSelector); >+}; >+ >+void TreeResolver::autosizeText() >+{ >+ HashSet<Element*> encountered; >+ const auto roots = m_update->roots(); >+ for (auto* root : roots) { >+ if (!root) >+ continue; >+ >+ AutosizeStatus status; >+ for (const auto& element : composedTreeAncestors(*root)) >+ status = apply(status, m_update->elementStyle(element)); >+ if (status.shouldSkipSubtree()) >+ continue; >+ >+ Vector<AutosizeStatus> stack; >+ stack.append(status); >+ auto adapter = composedTreeDescendants(*root); >+ auto iter = adapter.begin(); >+ auto baseDepth = iter.depth(); >+ for (; iter != adapter.end(); ++iter) { >+ auto& descendent = *iter; >+ if (!is<Element>(descendent)) >+ continue; >+ auto& element = downcast<Element>(descendent); >+ if (encountered.contains(&element)) >+ continue; >+ encountered.add(&element); >+ auto depth = iter.depth() - baseDepth + 1; >+ if (stack.size() > depth) >+ stack.shrink(depth); >+ auto* descendentStyle = m_update->elementStyle(element); >+ auto descendentStatus = apply(stack.last(), descendentStyle); >+ stack.reserveCapacity(depth); >+ while (stack.size() <= depth) >+ stack.uncheckedAppend(descendentStatus); >+ >+ if (descendentStatus.shouldSkipSubtree()) >+ continue; >+ >+ ASSERT(descendentStyle); >+ auto newTextSize = idempotentTextSize(descendentStyle->specifiedFontSize(), 0.666f); >+ >+ // FIXME: Deal with pseudo elements >+ // FIXME: Deal with list items >+ // FIXME: Deal with first letter >+ >+ if (auto* updates = m_update->elementUpdates(element)) { >+ auto* style = updates->update.style.get(); >+ ASSERT(style); >+ auto oldStyle = RenderStyle::clone(*style); >+ modifyStyleForAutosizing(*style, newTextSize, m_document.fontSelector()); >+ updates->update.change = determineChange(oldStyle, *style); >+ } else if (is<Element>(element.parentNode())) { >+ std::unique_ptr<RenderStyle> newStyle = RenderStyle::clonePtr(*descendentStyle); >+ modifyStyleForAutosizing(*newStyle, newTextSize, m_document.fontSelector()); >+ auto update = createAnimatedElementUpdate(WTFMove(newStyle), element, NoChange); >+ auto descendantsToResolve = DescendantsToResolve::None; >+ auto beforeUpdate = resolvePseudoStyle(element, update, PseudoId::Before); >+ auto afterUpdate = resolvePseudoStyle(element, update, PseudoId::After); >+ ElementUpdates elementUpdates = { WTFMove(update), descendantsToResolve, WTFMove(beforeUpdate), WTFMove(afterUpdate) }; >+ m_update->addElement(element, downcast<Element>(element.parentNode()), WTFMove(elementUpdates)); >+ } >+ } >+ } >+} >+#endif >+ > std::unique_ptr<Update> TreeResolver::resolve() > { > auto& renderView = *m_document.renderView(); >@@ -568,6 +733,11 @@ std::unique_ptr<Update> TreeResolver::resolve() > if (m_update->roots().isEmpty()) > return { }; > >+#if ENABLE(TEXT_AUTOSIZING) >+ if (m_document.settings().textAutosizingEnabled() && m_document.settings().textAutosizingUsesIdempotentMode()) >+ autosizeText(); >+#endif >+ > return WTFMove(m_update); > } > >diff --git a/Source/WebCore/style/StyleTreeResolver.h b/Source/WebCore/style/StyleTreeResolver.h >index 899a9f68ea651f9fc340e8c25a1b89e37ad1add9..7b1a5804df525aea6f8a52c1c5d7b5d02c7ba062 100644 >--- a/Source/WebCore/style/StyleTreeResolver.h >+++ b/Source/WebCore/style/StyleTreeResolver.h >@@ -54,6 +54,9 @@ public: > private: > std::unique_ptr<RenderStyle> styleForElement(Element&, const RenderStyle& inheritedStyle); > >+#if ENABLE(TEXT_AUTOSIZING) >+ void autosizeText(); >+#endif > void resolveComposedTree(); > > ElementUpdates resolveElement(Element&);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 197808
:
369628
|
369753
|
369914
|
369915
|
370290
|
370498
|
370542
|
370543
|
370558
|
370591
|
370606
|
370615
|
370617