Changeset 173941 in webkit
- Timestamp:
- Sep 24, 2014 7:32:06 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 2 deleted
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r173925 r173941 1 2014-09-22 Myles C. Maxfield <mmaxfield@apple.com> 2 3 REGRESSION: Text with a zero offset, zero blur shadow vanishes 4 https://bugs.webkit.org/show_bug.cgi?id=136801 5 6 Reviewed by Darin Adler. 7 8 This test should be a comprehensive test of empty shadows. It tests every 9 combination of one and two shadows being empty, as well as transparent and 10 opaque text. 11 12 After updating fast/text/empty-shadow.html, fast/text/empty-shadow-with-color.html 13 is no longer necessary. 14 15 * fast/text/empty-shadow-expected.html: 16 * fast/text/empty-shadow-with-color-expected.html: Removed. 17 * fast/text/empty-shadow-with-color.html: Removed. 18 * fast/text/empty-shadow.html: 19 1 20 2014-09-24 Shivakumar JM <shiva.jm@samsung.com> 2 21 -
trunk/LayoutTests/fast/text/empty-shadow-expected.html
r172153 r173941 1 This tests that text drawn with text-shadows of radius 0 and (0, 0) offset are not drawn. 2 This is a better outcome than them being drawn in an ugly way. 3 This test is successful if the text below is completely invisible. 1 <p>This tests that text drawn with text-shadows of radius 0 and (0, 0) offset are not drawn.</p> 2 <p>In the following tests, the actual text is green while the shadows are blue.</p> 3 4 <div style="color: green;"> 5 <div style="text-shadow: 5px 5px blue;">Text with a single shadow.</div> 6 <div>Text with one empty (undrawn) shadow.</div> 7 <div style="text-shadow: 5px 5px blue, 10px 10px blue;">Text with two shadows</div> 8 <div style="text-shadow: 5px 5px blue;">Text with two shadows: first drawn and second empty (undrawn).</div> 9 <div style="text-shadow: 10px 10px blue;">Text with two shadows: first empty (undrawn) and second drawn.</div> 10 <div>Text with two empty (undrawn) shadows.</div> 11 </div> 12 13 <div style="color: transparent;"> 14 <div style="text-shadow: 5px 5px blue;">Transparent text with a single shadow.</div> 15 <div style="color: blue;">Transparent text with one empty shadow.</div> 16 <div style="text-shadow: 5px 5px blue, 10px 10px blue;">Transparent text with two shadows</div> 17 <div style="color: blue; text-shadow: 7px 7px blue;">Transparent text with two shadows: first drawn and second empty.</div> 18 <div style="color: blue; text-shadow: 10px 10px blue;">Transparent text with two shadows: first drawn and second empty.</div> 19 <div style="color: blue; position: relative;"><div style="position: absolute; left: 0px; top: 0px;">Transparent text with two empty shadows.</div><div style="position: absolute; left: 0px; top: 0px;">Transparent text with two empty shadows.</div></div> 20 </div> -
trunk/LayoutTests/fast/text/empty-shadow.html
r172153 r173941 1 This tests that text drawn with text-shadows of radius 0 and (0, 0) offset are not drawn. 2 This is a better outcome than them being drawn in an ugly way. 3 This test is successful if the text below is completely invisible. 4 <div style="color:#fff;text-shadow:0 0 #000">This is some text</div> 1 <p>This tests that text drawn with text-shadows of radius 0 and (0, 0) offset are not drawn.</p> 2 <p>In the following tests, the actual text is green while the shadows are blue.</p> 3 4 <div style="color: green;"> 5 <div style="text-shadow: 5px 5px blue;">Text with a single shadow.</div> 6 <div style="text-shadow: 0px 0px blue;">Text with one empty (undrawn) shadow.</div> 7 <div style="text-shadow: 5px 5px blue, 10px 10px blue;">Text with two shadows</div> 8 <div style="text-shadow: 5px 5px blue, 0px 0px blue;">Text with two shadows: first drawn and second empty (undrawn).</div> 9 <div style="text-shadow: 0px 0px blue, 10px 10px blue;">Text with two shadows: first empty (undrawn) and second drawn.</div> 10 <div style="text-shadow: 0px 0px blue, 0px 0px blue;">Text with two empty (undrawn) shadows.</div> 11 </div> 12 13 <div style="color: transparent;"> 14 <div style="text-shadow: 5px 5px blue;">Transparent text with a single shadow.</div> 15 <div style="text-shadow: 0px 0px blue;">Transparent text with one empty shadow.</div> 16 <div style="text-shadow: 5px 5px blue, 10px 10px blue;">Transparent text with two shadows</div> 17 <div style="text-shadow: 7px 7px blue, 0px 0px blue;">Transparent text with two shadows: first drawn and second empty.</div> 18 <div style="text-shadow: 0px 0px blue, 10px 10px blue;">Transparent text with two shadows: first drawn and second empty.</div> 19 <div style="text-shadow: 0px 0px blue, 0px 0px blue;">Transparent text with two empty shadows.</div> 20 </div> -
trunk/Source/WebCore/ChangeLog
r173939 r173941 1 2014-09-22 Myles C. Maxfield <mmaxfield@apple.com> 2 3 REGRESSION: Text with a zero offset, zero blur shadow vanishes 4 https://bugs.webkit.org/show_bug.cgi?id=136801 5 6 Reviewed by Darin Adler. 7 8 This patch performs some cleanup regarding TextPainter's shadow logic and handles an 9 additional case of empty shadows. Previously, there was tight coupling between 10 applyShadowToGraphicalContext() and paintTextWithShadows(), as they both used a 11 collection of variables to determine how shadows are to be drawn. This complexity has 12 been moved into a helper class, ShadowApplier, which performs what 13 applyShadowToGraphicsContext() used to do, and cleans up correctly in its destructor. 14 This removes the tight coupling mentioned earlier. 15 16 Test: fast/text/empty-shadow.html 17 18 * rendering/InlineTextBox.cpp: 19 (WebCore::InlineTextBox::applyShadowToGraphicsContext): Moved to ShadowApplier. 20 * rendering/InlineTextBox.h: Deleted applyShadowToGraphicsContext signature. 21 * rendering/TextPainter.cpp: 22 (WebCore::ShadowApplier::ShadowApplier): Perform the contents of applyShadowToGraphicsContext() 23 (WebCore::ShadowApplier::~ShadowApplier): Undo the work done previously 24 (WebCore::paintTextWithShadows): Create a ShadowApplier to do the relevant shadow work. In addition, 25 refactor some boolean flags to more meaningful ones with relation to the computation at hand. 26 (WebCore::isEmptyShadow): Moved to TextPainter.h, named shadowIsCompletelyCoveredByText() 27 * rendering/TextPainter.h: 28 (WebCore::ShadowApplier::ShadowApplier): Moved from InlineTextBox::applyShadowToGraphicsContext(). 29 (WebCore::ShadowApplier::extraOffset): Getter. 30 (WebCore::ShadowApplier::~ShadowApplier): Moved from TextPainter::paintTextWithShadows(). 31 (WebCore::isLastShadowIteration): Helper function. 32 (WebCore::shadowIsCompletelyCoveredByText): Determines whether or not we should not draw the shadow. 33 * rendering/svg/SVGInlineTextBox.cpp: 34 (WebCore::SVGInlineTextBox::paintTextWithShadows): Update to use ShadowApplier. 35 1 36 2014-09-24 Brian J. Burg <burg@cs.washington.edu> 2 37 -
trunk/Source/WebCore/rendering/InlineTextBox.cpp
r173502 r173941 423 423 } 424 424 return false; 425 }426 427 FloatSize InlineTextBox::applyShadowToGraphicsContext(GraphicsContext& context, const ShadowData* shadow, const FloatRect& textRect, bool stroked, bool opaque, bool horizontal, bool& didSaveContext)428 {429 if (!shadow)430 return FloatSize();431 432 FloatSize extraOffset;433 int shadowX = horizontal ? shadow->x() : shadow->y();434 int shadowY = horizontal ? shadow->y() : -shadow->x();435 FloatSize shadowOffset(shadowX, shadowY);436 int shadowRadius = shadow->radius();437 const Color& shadowColor = shadow->color();438 439 if (shadow->next() || stroked || !opaque) {440 FloatRect shadowRect(textRect);441 shadowRect.inflate(shadow->paintingExtent());442 shadowRect.move(shadowOffset);443 context.save();444 context.clip(shadowRect);445 446 extraOffset = FloatSize(0, 2 * textRect.height() + std::max(0.0f, shadowOffset.height()) + shadowRadius);447 shadowOffset -= extraOffset;448 didSaveContext = true;449 }450 451 context.setShadow(shadowOffset, shadowRadius, shadowColor, context.fillColorSpace());452 return extraOffset;453 425 } 454 426 -
trunk/Source/WebCore/rendering/InlineTextBox.h
r173502 r173941 155 155 virtual float positionForOffset(int offset) const; 156 156 157 // Needs to be public, so the static paintTextWithShadows() function can use it.158 static FloatSize applyShadowToGraphicsContext(GraphicsContext&, const ShadowData*, const FloatRect& textRect, bool stroked, bool opaque, bool horizontal, bool& didSaveContext);159 160 157 protected: 161 158 void paintCompositionBackground(GraphicsContext*, const FloatPoint& boxOrigin, const RenderStyle&, const Font&, int startPos, int endPos); -
trunk/Source/WebCore/rendering/TextPainter.cpp
r173502 r173941 66 66 } 67 67 68 static bool isEmptyShadow(const ShadowData* shadow) 69 { 70 if (!shadow) 71 return false; 72 return shadow->location() == IntPoint() && !shadow->radius(); 68 ShadowApplier::ShadowApplier(GraphicsContext& context, const ShadowData* shadow, const FloatRect& textRect, bool lastShadowIterationShouldDrawText, bool opaque, FontOrientation orientation) 69 : m_context(context) 70 , m_shadow(shadow) 71 , m_onlyDrawsShadow(!isLastShadowIteration() || !lastShadowIterationShouldDrawText) 72 , m_avoidDrawingShadow(shadowIsCompletelyCoveredByText(opaque)) 73 , m_nothingToDraw(shadow && m_avoidDrawingShadow && m_onlyDrawsShadow) 74 , m_didSaveContext(false) 75 { 76 if (!shadow || m_nothingToDraw) { 77 m_shadow = nullptr; 78 return; 79 } 80 81 int shadowX = orientation == Horizontal ? shadow->x() : shadow->y(); 82 int shadowY = orientation == Horizontal ? shadow->y() : -shadow->x(); 83 FloatSize shadowOffset(shadowX, shadowY); 84 int shadowRadius = shadow->radius(); 85 const Color& shadowColor = shadow->color(); 86 87 // When drawing shadows, we usually clip the context to the area the shadow will reside, and then 88 // draw the text itself outside the clipped area (so only the shadow shows up). However, we can 89 // often draw the *last* shadow and the text itself in a single call. 90 if (m_onlyDrawsShadow) { 91 FloatRect shadowRect(textRect); 92 shadowRect.inflate(shadow->paintingExtent()); 93 shadowRect.move(shadowOffset); 94 context.save(); 95 context.clip(shadowRect); 96 97 m_didSaveContext = true; 98 m_extraOffset = FloatSize(0, 2 * textRect.height() + std::max(0.0f, shadowOffset.height()) + shadowRadius); 99 shadowOffset -= m_extraOffset; 100 } 101 102 if (!m_avoidDrawingShadow) 103 context.setShadow(shadowOffset, shadowRadius, shadowColor, context.fillColorSpace()); 104 } 105 106 ShadowApplier::~ShadowApplier() 107 { 108 if (!m_shadow) 109 return; 110 if (m_onlyDrawsShadow) 111 m_context.restore(); 112 else if (!m_avoidDrawingShadow) 113 m_context.clearShadow(); 73 114 } 74 115 … … 80 121 ColorSpace fillColorSpace = context.fillColorSpace(); 81 122 bool opaque = !fillColor.hasAlpha(); 123 bool lastShadowIterationShouldDrawText = !stroked && opaque; 82 124 if (!opaque) 83 125 context.setFillColor(Color::black, fillColorSpace); 84 126 85 127 do { 86 if (isEmptyShadow(shadow)) { 128 ShadowApplier shadowApplier(context, shadow, boxRect, lastShadowIterationShouldDrawText, opaque, horizontal ? Horizontal : Vertical); 129 if (shadowApplier.nothingToDraw()) { 87 130 shadow = shadow->next(); 88 131 continue; 89 132 } 90 133 91 IntSize extraOffset; 92 bool didSaveContext = false; 93 if (shadow) 94 extraOffset = roundedIntSize(InlineTextBox::applyShadowToGraphicsContext(context, shadow, boxRect, stroked, opaque, horizontal, didSaveContext)); 95 else if (!opaque) 134 IntSize extraOffset = roundedIntSize(shadowApplier.extraOffset()); 135 if (!shadow && !opaque) 96 136 context.setFillColor(fillColor, fillColorSpace); 97 137 … … 108 148 break; 109 149 110 if (didSaveContext)111 context.restore();112 else113 context.clearShadow();114 115 150 shadow = shadow->next(); 116 } while (shadow || stroked || !opaque);151 } while (shadow || !lastShadowIterationShouldDrawText); 117 152 } 118 153 -
trunk/Source/WebCore/rendering/TextPainter.h
r173502 r173941 26 26 #include "AffineTransform.h" 27 27 #include "DashArray.h" 28 #include "FontOrientation.h" 28 29 #include "RenderText.h" 29 30 … … 74 75 }; 75 76 77 class ShadowApplier { 78 public: 79 ShadowApplier(GraphicsContext&, const ShadowData*, const FloatRect& textRect, bool lastShadowIterationShouldDrawText = true, bool opaque = false, FontOrientation = Horizontal); 80 FloatSize extraOffset() const { return m_extraOffset; } 81 bool nothingToDraw() const { return m_nothingToDraw; } 82 bool didSaveContext() const { return m_didSaveContext; } 83 ~ShadowApplier(); 84 85 private: 86 bool isLastShadowIteration() 87 { 88 return m_shadow && !m_shadow->next(); 89 } 90 91 bool shadowIsCompletelyCoveredByText(bool textIsOpaque) 92 { 93 return textIsOpaque && shadow && m_shadow->location() == IntPoint() && !m_shadow->radius(); 94 } 95 96 FloatSize m_extraOffset; 97 GraphicsContext& m_context; 98 const ShadowData* m_shadow; 99 bool m_onlyDrawsShadow : 1; 100 bool m_avoidDrawingShadow : 1; 101 bool m_nothingToDraw : 1; 102 bool m_didSaveContext : 1; 103 }; 104 76 105 } // namespace WebCore 77 106 -
trunk/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
r173502 r173941 38 38 #include "SVGRootInlineBox.h" 39 39 #include "SVGTextRunRenderingContext.h" 40 #include "TextPainter.h" 40 41 41 42 namespace WebCore { … … 595 596 break; 596 597 597 FloatSize extraOffset; 598 bool didSaveContext = false; 599 if (shadow) 600 extraOffset = applyShadowToGraphicsContext(*context, shadow, shadowRect, false /* stroked */, true /* opaque */, true /* horizontal */, didSaveContext); 601 602 context->save(); 603 context->scale(FloatSize(1 / scalingFactor, 1 / scalingFactor)); 604 605 scaledFont.drawText(context, textRun, textOrigin + extraOffset, startPosition, endPosition); 606 607 context->restore(); 608 609 if (shadow) { 610 if (didSaveContext) 598 { 599 ShadowApplier shadowApplier(*context, shadow, shadowRect); 600 601 if (!shadowApplier.didSaveContext()) 602 context->save(); 603 context->scale(FloatSize(1 / scalingFactor, 1 / scalingFactor)); 604 605 scaledFont.drawText(context, textRun, textOrigin + shadowApplier.extraOffset(), startPosition, endPosition); 606 607 if (!shadowApplier.didSaveContext()) 611 608 context->restore(); 612 else613 context->clearShadow();614 609 } 615 610
Note: See TracChangeset
for help on using the changeset viewer.