Title: [168822] branches/safari-538.34-branch

Diff

Modified: branches/safari-538.34-branch/LayoutTests/ChangeLog (168821 => 168822)


--- branches/safari-538.34-branch/LayoutTests/ChangeLog	2014-05-14 08:57:48 UTC (rev 168821)
+++ branches/safari-538.34-branch/LayoutTests/ChangeLog	2014-05-14 09:03:09 UTC (rev 168822)
@@ -1,5 +1,27 @@
 2014-05-14  Lucas Forschler  <[email protected]>
 
+        Merge r168750
+
+    2014-05-13  Myles C. Maxfield  <[email protected]>
+
+            Text decorations do not contribute to visual overflow
+            https://bugs.webkit.org/show_bug.cgi?id=132773
+
+            Reviewed by Darin Adler.
+
+            This test makes sure that repaint rects are extended to include text decorations that may
+            lie outside of the text layout rects. It compares text with an underline to text that has
+            had underline applied to it in a timer.
+
+            * fast/css3-text/css3-text-decoration/repaint/resources/Litherum.svg: Added. This font has a
+            descent of 0 (so it will not intersect underlines)
+            * fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-expected.html: Added.
+            Apply the underline without any timeout
+            * fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect.html: Added.
+            Apply the underline with a timeout.
+
+2014-05-14  Lucas Forschler  <[email protected]>
+
         Merge r168599
 
     2014-05-09  Myles C. Maxfield  <[email protected]>

Copied: branches/safari-538.34-branch/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-expected.html (from rev 168750, trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-expected.html) (0 => 168822)


--- branches/safari-538.34-branch/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-expected.html	                        (rev 0)
+++ branches/safari-538.34-branch/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect-expected.html	2014-05-14 09:03:09 UTC (rev 168822)
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+    font-family: 'Litherum';
+    src: url("./resources/Litherum.svg") format(svg)
+}
+div {
+    font-family: 'Litherum';
+    -webkit-text-decoration-skip: none;
+    -webkit-text-decoration-color: green;
+    width: 1px;
+    height: 1px;
+}
+</style>
+</head>
+<body>
+This test makes sure that underlines contribute to visual overflow.
+The SVG font has a descent of 0, which means that underlines will
+lie outside of the glyph boundaries. The test makes sure that
+drawing underlined text ends up the same as drawing text that has
+had the underline retroactively applied to it with _javascript_.
+<div style="position: relative">
+<div id="underline" style="position: absolute; left: 0px; top: 0px; text-decoration: underline;">|</div>
+<div id="underlineunder" style="position: absolute; left: 20px; top: 0px; -webkit-text-underline-position: under; text-decoration: underline">|</div>
+<div id="linethrough" style="position: absolute; left: 40px; top: 0px; text-decoration: line-through;">|</div>
+<div id="overline" style="position: absolute; left: 60px; top: 0px; text-decoration: overline;">|</div>
+
+<div id="wavyunderline" style="position: absolute; left: 0px; top: 20px; -webkit-text-decoration-style: wavy; text-decoration: underline;">|</div>
+<div id="wavyunderlineunder" style="position: absolute; left: 20px; top: 20px; -webkit-text-underline-position: under; -webkit-text-decoration-style: wavy; text-decoration: underline;">|</div>
+<div id="wavylinethrough" style="font-size: 1px; position: absolute; left: 40px; top: 20px; -webkit-text-decoration-style: wavy; text-decoration: line-through;">-</div>
+<div id="wavyoverline" style="position: absolute; left: 60px; top: 20px; -webkit-text-decoration-style: wavy; text-decoration: overline;">|</div>
+</div>
+</body>
+</html>

Copied: branches/safari-538.34-branch/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect.html (from rev 168750, trunk/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect.html) (0 => 168822)


--- branches/safari-538.34-branch/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect.html	                        (rev 0)
+++ branches/safari-538.34-branch/LayoutTests/fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect.html	2014-05-14 09:03:09 UTC (rev 168822)
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+    font-family: 'Litherum';
+    src: url("./resources/Litherum.svg") format(svg)
+}
+div {
+    font-family: 'Litherum';
+    -webkit-text-decoration-skip: none;
+    -webkit-text-decoration-color: green;
+    width: 1px;
+    height: 1px;
+}
+</style>
+</head>
+<body>
+This test makes sure that underlines contribute to visual overflow.
+The SVG font has a descent of 0, which means that underlines will
+lie outside of the glyph boundaries. The test makes sure that
+drawing underlined text ends up the same as drawing text that has
+had the underline retroactively applied to it with _javascript_.
+<div style="position: relative">
+<div id="underline" style="position: absolute; left: 0px; top: 0px;">|</div>
+<div id="underlineunder" style="position: absolute; left: 20px; top: 0px; -webkit-text-underline-position: under;">|</div>
+<div id="linethrough" style="position: absolute; left: 40px; top: 0px;">|</div>
+<div id="overline" style="position: absolute; left: 60px; top: 0px;">|</div>
+
+<div id="wavyunderline" style="position: absolute; left: 0px; top: 20px; -webkit-text-decoration-style: wavy;">|</div>
+<div id="wavyunderlineunder" style="position: absolute; left: 20px; top: 20px; -webkit-text-underline-position: under; -webkit-text-decoration-style: wavy;">|</div>
+<div id="wavylinethrough" style="font-size: 1px; position: absolute; left: 40px; top: 20px; -webkit-text-decoration-style: wavy;">-</div>
+<div id="wavyoverline" style="position: absolute; left: 60px; top: 20px; -webkit-text-decoration-style: wavy;">|</div>
+</div>
+<script>
+function applyUnderline() {
+    document.getElementById('underline').style.textDecoration = "underline";
+    document.getElementById('underlineunder').style.textDecoration = "underline";
+    document.getElementById('linethrough').style.textDecoration = "line-through";
+    document.getElementById('overline').style.textDecoration = "overline";
+    document.getElementById('wavyunderline').style.textDecoration = "underline";
+    document.getElementById('wavyunderlineunder').style.textDecoration = "underline";
+    document.getElementById('wavylinethrough').style.textDecoration = "line-through";
+    document.getElementById('wavyoverline').style.textDecoration = "overline";
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+
+if (window.testRunner)
+    testRunner.waitUntilDone();
+window.addEventListener('load', applyUnderline, false);
+</script>
+</body>
+</html>

Modified: branches/safari-538.34-branch/Source/WebCore/ChangeLog (168821 => 168822)


--- branches/safari-538.34-branch/Source/WebCore/ChangeLog	2014-05-14 08:57:48 UTC (rev 168821)
+++ branches/safari-538.34-branch/Source/WebCore/ChangeLog	2014-05-14 09:03:09 UTC (rev 168822)
@@ -1,5 +1,35 @@
 2014-05-14  Lucas Forschler  <[email protected]>
 
+        Merge r168750
+
+    2014-05-13  Myles C. Maxfield  <[email protected]>
+
+            Text decorations do not contribute to visual overflow
+            https://bugs.webkit.org/show_bug.cgi?id=132773
+
+            Reviewed by Darin Adler.
+
+            Tests: fast/css3-text/css3-text-decoration/repaint/underline-outside-of-layout-rect.html
+
+            * rendering/InlineTextBox.cpp:
+            (WebCore::textDecorationStrokeThickness): Refactor into a common function
+            (WebCore::wavyOffsetFromDecoration): Ditto
+            (WebCore::InlineTextBox::extendVerticalVisualOverflowForDecorations): Given
+            vertical overflow bounds, possibly extend those to include location of
+            decorations.
+            (WebCore::InlineTextBox::paintDecoration): Use refactored functions.
+            * rendering/InlineTextBox.h: Function signature
+            * rendering/RenderBlockLineLayout.cpp:
+            (WebCore::setLogicalWidthForTextRun): Call extendVerticalVisualOverflowForDecorations()
+            * rendering/style/RenderStyle.cpp:
+            (WebCore::RenderStyle::changeAffectsVisualOverflow): Inspects shadows and text decorations
+            (WebCore::RenderStyle::changeRequiresLayout): Calls changeAffectsVisualOverflow()
+            (WebCore::RenderStyle::changeRequiresRepaintIfTextOrBorderOrOutline): Moved code from here
+            to changeAffectsVisualOverflow().
+            * rendering/style/RenderStyle.h: Function signature
+
+2014-05-14  Lucas Forschler  <[email protected]>
+
         Merge r168599
 
     2014-05-09  Myles C. Maxfield  <[email protected]>

Modified: branches/safari-538.34-branch/Source/WebCore/rendering/InlineTextBox.cpp (168821 => 168822)


--- branches/safari-538.34-branch/Source/WebCore/rendering/InlineTextBox.cpp	2014-05-14 08:57:48 UTC (rev 168821)
+++ branches/safari-538.34-branch/Source/WebCore/rendering/InlineTextBox.cpp	2014-05-14 09:03:09 UTC (rev 168822)
@@ -975,6 +975,71 @@
     context.strokePath(path);
 }
 
+static inline float textDecorationStrokeThickness(float fontSize)
+{
+    const float textDecorationBaseFontSize = 16;
+    return fontSize / textDecorationBaseFontSize;
+}
+
+static inline float wavyOffsetFromDecoration()
+{
+    return 2;
+}
+
+void InlineTextBox::extendVerticalVisualOverflowForDecorations(float& top, float& bottom) const
+{
+    const RenderStyle& lineStyle = this->lineStyle();
+    TextDecoration decoration = lineStyle.textDecorationsInEffect();
+    
+    if (decoration == TextDecorationNone)
+        return;
+    
+    TextDecorationStyle decorationStyle = lineStyle.textDecorationStyle();
+    float strokeThickness = textDecorationStrokeThickness(renderer().style().fontSize());
+    
+    float controlPointDistance;
+    float step;
+    float wavyOffset;
+    
+    if (decorationStyle == TextDecorationStyleWavy) {
+        getWavyStrokeParameters(strokeThickness, controlPointDistance, step);
+        wavyOffset = wavyOffsetFromDecoration();
+    }
+    
+    float height = logicalHeight();
+
+    // These metrics must match where underlines get drawn.
+    if (decoration & TextDecorationUnderline) {
+        float underlineOffset = computeUnderlineOffset(lineStyle.textUnderlinePosition(), lineStyle.fontMetrics(), this, strokeThickness);
+        if (decorationStyle == TextDecorationStyleWavy) {
+            bottom = std::max(bottom, underlineOffset + wavyOffset + controlPointDistance + strokeThickness - height);
+            top = std::max(top, -(underlineOffset + wavyOffset - controlPointDistance - strokeThickness));
+        } else {
+            bottom = std::max(bottom, underlineOffset + strokeThickness - height);
+            top = std::max(top, -underlineOffset);
+        }
+    }
+    if (decoration & TextDecorationOverline) {
+        if (decorationStyle == TextDecorationStyleWavy) {
+            bottom = std::max(bottom, -wavyOffset + controlPointDistance + strokeThickness - height);
+            top = std::max(top, wavyOffset + controlPointDistance + strokeThickness);
+        } else {
+            bottom = std::max(bottom, strokeThickness - height);
+            // top is untouched
+        }
+    }
+    if (decoration & TextDecorationLineThrough) {
+        float baseline = lineStyle.fontMetrics().floatAscent();
+        if (decorationStyle == TextDecorationStyleWavy) {
+            bottom = std::max(bottom, 2 * baseline / 3 + controlPointDistance + strokeThickness - height);
+            top = std::max(top, -(2 * baseline / 3 - controlPointDistance - strokeThickness));
+        } else {
+            bottom = std::max(bottom, 2 * baseline / 3 + strokeThickness - height);
+            top = std::max(top, -(2 * baseline / 3));
+        }
+    }
+}
+
 void InlineTextBox::paintDecoration(GraphicsContext& context, const FloatPoint& boxOrigin, TextDecoration decoration, TextDecorationStyle decorationStyle, const ShadowData* shadow, TextPainter& textPainter)
 {
 #if !ENABLE(CSS3_TEXT_DECORATION_SKIP_INK)
@@ -1002,8 +1067,7 @@
     // Use a special function for underlines to get the positioning exactly right.
     bool isPrinting = renderer().document().printing();
 
-    const float textDecorationBaseFontSize = 16;
-    float textDecorationThickness = renderer().style().fontSize() / textDecorationBaseFontSize;
+    float textDecorationThickness = textDecorationStrokeThickness(renderer().style().fontSize());
     context.setStrokeThickness(textDecorationThickness);
 
     bool linesAreOpaque = !isPrinting && (!(decoration & TextDecorationUnderline) || underline.alpha() == 255) && (!(decoration & TextDecorationOverline) || overline.alpha() == 255) && (!(decoration & TextDecorationLineThrough) || linethrough.alpha() == 255);
@@ -1049,13 +1113,13 @@
             shadow = shadow->next();
         }
         
-        float wavyOffset = 2.f;
+        float wavyOffset = wavyOffsetFromDecoration();
 
         context.setStrokeStyle(textDecorationStyleToStrokeStyle(decorationStyle));
+        // These decorations should match the visual overflows computed in extendVerticalVisualOverflowForDecorations()
         if (decoration & TextDecorationUnderline) {
             context.setStrokeColor(underline, colorSpace);
-            TextUnderlinePosition underlinePosition = lineStyle.textUnderlinePosition();
-            const int underlineOffset = computeUnderlineOffset(underlinePosition, lineStyle.fontMetrics(), this, textDecorationThickness);
+            const int underlineOffset = computeUnderlineOffset(lineStyle.textUnderlinePosition(), lineStyle.fontMetrics(), this, textDecorationThickness);
 
             switch (decorationStyle) {
             case TextDecorationStyleWavy: {

Modified: branches/safari-538.34-branch/Source/WebCore/rendering/InlineTextBox.h (168821 => 168822)


--- branches/safari-538.34-branch/Source/WebCore/rendering/InlineTextBox.h	2014-05-14 08:57:48 UTC (rev 168821)
+++ branches/safari-538.34-branch/Source/WebCore/rendering/InlineTextBox.h	2014-05-14 09:03:09 UTC (rev 168822)
@@ -159,6 +159,7 @@
 public:
     virtual int offsetForPosition(float x, bool includePartialGlyphs = true) const;
     virtual float positionForOffset(int offset) const;
+    void extendVerticalVisualOverflowForDecorations(float& top, float& bottom) const;
 
     // Needs to be public, so the static paintTextWithShadows() function can use it.
     static FloatSize applyShadowToGraphicsContext(GraphicsContext*, const ShadowData*, const FloatRect& textRect, bool stroked, bool opaque, bool horizontal);

Modified: branches/safari-538.34-branch/Source/WebCore/rendering/RenderBlockLineLayout.cpp (168821 => 168822)


--- branches/safari-538.34-branch/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2014-05-14 08:57:48 UTC (rev 168821)
+++ branches/safari-538.34-branch/Source/WebCore/rendering/RenderBlockLineLayout.cpp	2014-05-14 09:03:09 UTC (rev 168822)
@@ -524,7 +524,17 @@
         copyToVector(fallbackFonts, it->value.first);
         run->box()->parent()->clearDescendantsHaveSameLineHeightAndBaseline();
     }
-    if ((glyphOverflow.top || glyphOverflow.bottom || glyphOverflow.left || glyphOverflow.right)) {
+
+    // Include text decoration visual overflow as part of the glyph overflow.
+    if (renderer->style().textDecorationsInEffect() != TextDecorationNone) {
+        float top = glyphOverflow.top;
+        float bottom = glyphOverflow.bottom;
+        toInlineTextBox(run->box())->extendVerticalVisualOverflowForDecorations(top, bottom);
+        glyphOverflow.top = static_cast<int>(ceilf(top));
+        glyphOverflow.bottom = static_cast<int>(ceilf(bottom));
+    }
+
+    if (glyphOverflow.top || glyphOverflow.bottom || glyphOverflow.left || glyphOverflow.right) {
         ASSERT(run->box()->behavesLikeText());
         GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.add(toInlineTextBox(run->box()), std::make_pair(Vector<const SimpleFontData*>(), GlyphOverflow())).iterator;
         it->value.second = glyphOverflow;

Modified: branches/safari-538.34-branch/Source/WebCore/rendering/style/RenderStyle.cpp (168821 => 168822)


--- branches/safari-538.34-branch/Source/WebCore/rendering/style/RenderStyle.cpp	2014-05-14 08:57:48 UTC (rev 168821)
+++ branches/safari-538.34-branch/Source/WebCore/rendering/style/RenderStyle.cpp	2014-05-14 09:03:09 UTC (rev 168822)
@@ -382,6 +382,22 @@
     return true;
 }
 
+inline bool RenderStyle::changeAffectsVisualOverflow(const RenderStyle& other) const
+{
+    if (rareNonInheritedData.get() != other.rareNonInheritedData.get()
+        && !rareNonInheritedData->shadowDataEquivalent(*other.rareNonInheritedData.get()))
+        return true;
+
+    if (inherited_flags._text_decorations != other.inherited_flags._text_decorations
+        || visual->textDecoration != other.visual->textDecoration
+        || rareNonInheritedData->m_textDecorationStyle != other.rareNonInheritedData->m_textDecorationStyle
+        || rareNonInheritedData->m_textDecorationColor != other.rareNonInheritedData->m_textDecorationColor
+        || rareInheritedData->m_textDecorationSkip != other.rareInheritedData->m_textDecorationSkip)
+        return true;
+
+    return false;
+}
+
 bool RenderStyle::changeRequiresLayout(const RenderStyle* other, unsigned& changedContextSensitiveProperties) const
 {
     if (m_box->width() != other->m_box->width()
@@ -404,6 +420,10 @@
     if (surround->padding != other->surround->padding)
         return true;
 
+    // FIXME: We should add an optimized form of layout that just recomputes visual overflow.
+    if (changeAffectsVisualOverflow(*other))
+        return true;
+
     if (rareNonInheritedData.get() != other->rareNonInheritedData.get()) {
         if (rareNonInheritedData->m_appearance != other->rareNonInheritedData->m_appearance 
             || rareNonInheritedData->marginBeforeCollapse != other->rareNonInheritedData->marginBeforeCollapse
@@ -434,10 +454,6 @@
             || rareNonInheritedData->m_justifyContent != other->rareNonInheritedData->m_justifyContent)
             return true;
 
-        // FIXME: We should add an optimized form of layout that just recomputes visual overflow.
-        if (!rareNonInheritedData->shadowDataEquivalent(*other->rareNonInheritedData.get()))
-            return true;
-
         if (!rareNonInheritedData->reflectionDataEquivalent(*other->rareNonInheritedData.get()))
             return true;
 
@@ -717,11 +733,6 @@
 bool RenderStyle::changeRequiresRepaintIfTextOrBorderOrOutline(const RenderStyle* other, unsigned&) const
 {
     if (inherited->color != other->inherited->color
-        || inherited_flags._text_decorations != other->inherited_flags._text_decorations
-        || visual->textDecoration != other->visual->textDecoration
-        || rareNonInheritedData->m_textDecorationStyle != other->rareNonInheritedData->m_textDecorationStyle
-        || rareNonInheritedData->m_textDecorationColor != other->rareNonInheritedData->m_textDecorationColor
-        || rareInheritedData->m_textDecorationSkip != other->rareInheritedData->m_textDecorationSkip
         || rareInheritedData->textFillColor != other->rareInheritedData->textFillColor
         || rareInheritedData->textStrokeColor != other->rareInheritedData->textStrokeColor
         || rareInheritedData->textEmphasisColor != other->rareInheritedData->textEmphasisColor

Modified: branches/safari-538.34-branch/Source/WebCore/rendering/style/RenderStyle.h (168821 => 168822)


--- branches/safari-538.34-branch/Source/WebCore/rendering/style/RenderStyle.h	2014-05-14 08:57:48 UTC (rev 168821)
+++ branches/safari-538.34-branch/Source/WebCore/rendering/style/RenderStyle.h	2014-05-14 09:03:09 UTC (rev 168822)
@@ -1936,6 +1936,7 @@
     static ptrdiff_t noninheritedFlagsMemoryOffset() { return OBJECT_OFFSETOF(RenderStyle, noninherited_flags); }
 
 private:
+    bool changeAffectsVisualOverflow(const RenderStyle&) const;
     bool changeRequiresLayout(const RenderStyle*, unsigned& changedContextSensitiveProperties) const;
     bool changeRequiresPositionedLayoutOnly(const RenderStyle*, unsigned& changedContextSensitiveProperties) const;
     bool changeRequiresLayerRepaint(const RenderStyle*, unsigned& changedContextSensitiveProperties) const;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to