Changeset 69681 in webkit
- Timestamp:
- Oct 13, 2010 12:18:10 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 63 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r69679 r69681 1 2010-09-24 Martin Robinson <mrobinson@igalia.com> 2 3 Reviewed by Dirk Schulze. 4 5 [Cairo] Activate ContextShadow in all places where shadows are drawn 6 https://bugs.webkit.org/show_bug.cgi?id=46475 7 8 Rebaselined tests. All these changes seem reasonable. In some cases, the 9 new results are much better / closer matches to Chromium. 10 11 * platform/gtk/fast/box-shadow/basic-shadows-expected.checksum: 12 * platform/gtk/fast/box-shadow/basic-shadows-expected.png: 13 * platform/gtk/fast/box-shadow/inset-expected.checksum: 14 * platform/gtk/fast/box-shadow/inset-expected.png: 15 * platform/gtk/fast/css/shadow-multiple-expected.checksum: 16 * platform/gtk/fast/css/shadow-multiple-expected.png: 17 * platform/gtk/fast/text/shadow-no-blur-expected.checksum: 18 * platform/gtk/fast/text/shadow-no-blur-expected.png: 19 * platform/gtk/fast/text/shadow-translucent-fill-expected.checksum: 20 * platform/gtk/fast/text/shadow-translucent-fill-expected.png: 21 * platform/gtk/fast/text/stroking-decorations-expected.checksum: 22 * platform/gtk/fast/text/stroking-decorations-expected.png: 23 * platform/gtk/fast/text/stroking-expected.checksum: 24 * platform/gtk/fast/text/stroking-expected.png: 25 * platform/gtk/fast/transforms/shadows-expected.checksum: 26 * platform/gtk/fast/transforms/shadows-expected.png: 27 * platform/gtk/svg/css/arrow-with-shadow-expected.checksum: 28 * platform/gtk/svg/css/arrow-with-shadow-expected.png: 29 * platform/gtk/svg/css/composite-shadow-text-expected.checksum: 30 * platform/gtk/svg/css/composite-shadow-text-expected.png: 31 * platform/gtk/svg/css/group-with-shadow-expected.checksum: 32 * platform/gtk/svg/css/group-with-shadow-expected.png: 33 * platform/gtk/svg/css/path-with-shadow-expected.checksum: 34 * platform/gtk/svg/css/path-with-shadow-expected.png: 35 * platform/gtk/svg/css/shadow-with-large-radius-expected.checksum: 36 * platform/gtk/svg/css/shadow-with-large-radius-expected.png: 37 * platform/gtk/svg/css/shadow-with-negative-offset-expected.checksum: 38 * platform/gtk/svg/css/shadow-with-negative-offset-expected.png: 39 1 40 2010-10-13 Nate Chapin <japhet@chromium.org> 2 41 -
trunk/LayoutTests/platform/gtk/fast/box-shadow/basic-shadows-expected.checksum
r66607 r69681 1 6daac1f7e6af1534a5d83a808573a5c6 1 f3de98a36ced3833112c6a4015124c40 -
trunk/LayoutTests/platform/gtk/fast/box-shadow/border-radius-big-expected.checksum
r66393 r69681 1 f0c925808e96b7a3c3fb3dd6af9f0bef 1 0f81b48394aca674d7d6fda921894590 -
trunk/LayoutTests/platform/gtk/fast/box-shadow/inset-expected.checksum
r66393 r69681 1 6d342f464b9c3b1b359652690668b018 1 031c0afbbbf2d3d170b1d5ec47340360 -
trunk/LayoutTests/platform/gtk/fast/box-shadow/spread-expected.checksum
r66393 r69681 1 725db46a3dfc6bd70efff487e32b54c9 1 47ae516cd0eb09ddb903c4faee42bc6d -
trunk/LayoutTests/platform/gtk/fast/box-shadow/transform-fringing-expected.checksum
r66393 r69681 1 66269bba477ba14b5f904c3edcd7a596 1 06d7219b65698e41236bf902fc140a4e -
trunk/LayoutTests/platform/gtk/fast/canvas/shadow-offset-1-expected.checksum
r66393 r69681 1 b24d55d0a3671f2e40ff90f9515b8f00 1 0c1b31a0c94ec92859e1de91bf1c1c56 -
trunk/LayoutTests/platform/gtk/fast/canvas/shadow-offset-2-expected.checksum
r66393 r69681 1 701883d2e2f95b9d50212bdc39fb59d8 1 c56a7a9113871adb1a75a08af85ab186 -
trunk/LayoutTests/platform/gtk/fast/canvas/shadow-offset-3-expected.checksum
r66393 r69681 1 b24d55d0a3671f2e40ff90f9515b8f00 1 0c1b31a0c94ec92859e1de91bf1c1c56 -
trunk/LayoutTests/platform/gtk/fast/canvas/shadow-offset-4-expected.checksum
r66393 r69681 1 63cb5d33757a90a841d654189f713879 1 10a69afccdf47959f6aee5a2c4e1ef66 -
trunk/LayoutTests/platform/gtk/fast/canvas/shadow-offset-5-expected.checksum
r66393 r69681 1 63cb5d33757a90a841d654189f713879 1 10a69afccdf47959f6aee5a2c4e1ef66 -
trunk/LayoutTests/platform/gtk/fast/canvas/shadow-offset-6-expected.checksum
r66393 r69681 1 db6adefba05e354dd1d2e812f8c84714 1 b50f28ba9f5040841ee6ce23e85ee986 -
trunk/LayoutTests/platform/gtk/fast/canvas/shadow-offset-7-expected.checksum
r66393 r69681 1 7251d5e6065a233d322bf895b73cde6d 1 f349f090b70db32dee81d2e646d3a807 -
trunk/LayoutTests/platform/gtk/fast/css/shadow-multiple-expected.checksum
r69558 r69681 1 701fabbd3a807c01bb522ec6f2d85122 1 c5e2b47412e5f8bd9d491052823d7ffa -
trunk/LayoutTests/platform/gtk/fast/forms/box-shadow-override-expected.checksum
r66393 r69681 1 0c3455ef1a424a2702d95d377ca19e1a 1 99b1869ec4d61313015fd2f3b02f3fdf -
trunk/LayoutTests/platform/gtk/fast/text/shadow-translucent-fill-expected.checksum
r63212 r69681 1 ce7b93fc7b29c0f7f9a879369f39159a 1 4844ccf7d596f6f8e3f7b47028101646 -
trunk/LayoutTests/platform/gtk/fast/text/stroking-decorations-expected.checksum
r63176 r69681 1 8fe4216cf5158e1a48ff9a096e73c49c 1 a8d29b21cf38133e73674466c89ae4d9 -
trunk/LayoutTests/platform/gtk/fast/text/stroking-decorations-expected.txt
r63176 r69681 4 4 RenderBlock {HTML} at (0,0) size 800x600 5 5 RenderBody {BODY} at (8,8) size 784x584 6 RenderBlock {DIV} at (0,0) size 784x1 56[textFillColor=#800080] [textStrokeWidth=2.00]7 RenderText {#text} at (0, 0) size 759x1568 text run at (0, 0) width 690: "Purple\x{300} fill, black stroke,"9 text run at (0,7 8) width 759: "complex text, black underline"10 RenderBlock {DIV} at (0,1 56) size 784x156[textStrokeColor=#FFA500] [textStrokeWidth=1.33]11 RenderText {#text} at (0, 0) size 636x15612 text run at (0, 0) width 636: "Orange stroke, black fill,"13 text run at (0,7 8) width 414: "orange overline."14 RenderBlock {DIV} at (0, 312) size 784x156[textFillColor=#0000FF] [textStrokeWidth=1.33]15 RenderText {#text} at (0, 0) size 596x15616 text run at (0, 0) width 596: "No stroke, blue fill, red"17 text run at (0,7 8) width 594: "shadow, blue underline"6 RenderBlock {DIV} at (0,0) size 784x148 [textFillColor=#800080] [textStrokeWidth=2.00] 7 RenderText {#text} at (0,1) size 755x146 8 text run at (0,1) width 616: "Purple\x{300} fill, black stroke," 9 text run at (0,75) width 755: "complex text, black underline" 10 RenderBlock {DIV} at (0,148) size 784x148 [textStrokeColor=#FFA500] [textStrokeWidth=1.33] 11 RenderText {#text} at (0,1) size 633x146 12 text run at (0,1) width 633: "Orange stroke, black fill," 13 text run at (0,75) width 412: "orange overline." 14 RenderBlock {DIV} at (0,296) size 784x148 [textFillColor=#0000FF] [textStrokeWidth=1.33] 15 RenderText {#text} at (0,1) size 593x146 16 text run at (0,1) width 593: "No stroke, blue fill, red" 17 text run at (0,75) width 592: "shadow, blue underline" -
trunk/LayoutTests/platform/gtk/fast/text/stroking-expected.checksum
r63176 r69681 1 9bda69d71f92b48dcbeadbc97d4aa3141 1dbe4580c4247c66169215a291f01784 -
trunk/LayoutTests/platform/gtk/fast/transforms/shadows-expected.checksum
r66393 r69681 1 53b5647f358b53516a2971cef984ef43 1 643ebb3d9f814c590c1360ee8780a711 -
trunk/LayoutTests/platform/gtk/svg/css/arrow-with-shadow-expected.checksum
r66393 r69681 1 60406d17eccb661d0abcd479d52d18ae 1 7d901aa9e6137f3d4eb0ecffa0a0f6f1 -
trunk/LayoutTests/platform/gtk/svg/css/composite-shadow-example-expected.checksum
r66400 r69681 1 e b02e2baeae31fc65b216461d6335e4e1 ed68ae2b7a0581824bc52f03f4c24081 -
trunk/LayoutTests/platform/gtk/svg/css/composite-shadow-text-expected.checksum
r66400 r69681 1 fa62fff1ff8a295928c6e40d613d036e 1 ed041c188a24404f25bd470e8b6897c7 -
trunk/LayoutTests/platform/gtk/svg/css/group-with-shadow-expected.checksum
r66393 r69681 1 934838cc206f3bb144a04f0ec0c66fd6 1 b9583689ec16aa6f14a1b326dc4efb20 -
trunk/LayoutTests/platform/gtk/svg/css/mask-with-shadow-expected.checksum
r66393 r69681 1 95a13b575496a68e7be1e244fc085917 1 fccfdd6c1ec02071e92cf8d3e4e055a4 -
trunk/LayoutTests/platform/gtk/svg/css/path-with-shadow-expected.checksum
r66393 r69681 1 5d5b77a6e165e0386e1ed99ca462e546 1 32a221a08c690feca7b5f130b0f2b878 -
trunk/LayoutTests/platform/gtk/svg/css/shadow-with-large-radius-expected.checksum
r66400 r69681 1 986e969dd5390eec347bde78441e9610 1 323c4bac52ad86e6f6a1428e85acbf35 -
trunk/LayoutTests/platform/gtk/svg/css/shadow-with-negative-offset-expected.checksum
r66400 r69681 1 3676ffa41f1289d75c2a94d625be27c4 1 a2bc3466efff610dd09fdc9969d0b756 -
trunk/LayoutTests/platform/gtk/svg/css/stars-with-shadow-expected.checksum
r66607 r69681 1 cf31a5f1ae3ef8dd8bba3df35e5ebb9b 1 88f3dc364c44bdaa92e09d883c6f7609 -
trunk/WebCore/ChangeLog
r69673 r69681 1 2010-10-06 Martin Robinson <mrobinson@igalia.com> 2 3 Reviewed by Dirk Schulze. 4 5 [Cairo] Activate ContextShadow in all places where shadows are drawn 6 https://bugs.webkit.org/show_bug.cgi?id=46475 7 8 Turn on ContextShadow for the Cairo port and remove all old shadow code. 9 Shadow tiling optimizations will be added in a followup patch to ContextShadowCairo. 10 11 * platform/graphics/GraphicsContext.h: Add a ContextShadow forward declaration for Cairo. 12 * platform/graphics/cairo/FontCairo.cpp: Switch to using ContextShadow. 13 (WebCore::prepareContextForGlyphDrawing): Added this helper which sets up the translation 14 on the specified cairo_t to prepare for drawing glyphs. 15 (WebCore::drawGlyphsToContext): Added this helper which draws the glyphs to a cairo_t, 16 while properly handling glyphs with synthetic bold. 17 (WebCore::Font::drawGlyphs): Removed old shadow code and replaced it with ContextShadow usage. 18 * platform/graphics/cairo/GraphicsContextCairo.cpp: 19 (WebCore::drawPathShadow): Modified this to use ContextShadow and to take an enum 20 argument specifying whether to fill or stroke the solid figure for the shadow. 21 (WebCore::fillCurrentCairoPath): Updated drawPathShadow call. 22 (WebCore::strokeCurrentCairoPath): Ditto. 23 (WebCore::GraphicsContext::savePlatformState): Save the ContextShadow. 24 (WebCore::GraphicsContext::restorePlatformState): Restore the ContextShadow. 25 (WebCore::GraphicsContext::drawPath): Updated drawPathShadow call. 26 (WebCore::GraphicsContext::fillRect): Uses ContextShadow now. 27 (WebCore::GraphicsContext::setPlatformShadow): Uses ContextShadow now. 28 (WebCore::GraphicsContext::contextShadow): Added. 29 (WebCore::GraphicsContext::clearPlatformShadow): Clears the ContextShadow member. 30 (WebCore::GraphicsContext::fillRoundedRect): Updated drawPathShadow call. 31 * platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h: 32 (WebCore::GraphicsContextPlatformPrivate::hasShadow): Added. 33 * platform/graphics/cairo/ImageCairo.cpp: 34 (WebCore::BitmapImage::draw): Updated to use ContextShadow. 35 1 36 2010-10-13 John Knottenbelt <jknotten@chromium.org> 2 37 -
trunk/WebCore/platform/graphics/ContextShadow.h
r69223 r69681 101 101 static void purgeScratchBuffer(); 102 102 #if PLATFORM(CAIRO) 103 void drawRectShadow(GraphicsContext* context, const IntRect& rect, const IntSize& topLeftRadius , const IntSize& topRightRadius, const IntSize& bottomLeftRadius, const IntSize& bottomRightRadius);103 void drawRectShadow(GraphicsContext* context, const IntRect& rect, const IntSize& topLeftRadius = IntSize(), const IntSize& topRightRadius = IntSize(), const IntSize& bottomLeftRadius = IntSize(), const IntSize& bottomRightRadius = IntSize()); 104 104 #endif 105 105 -
trunk/WebCore/platform/graphics/GraphicsContext.h
r69187 r69681 42 42 #elif PLATFORM(CAIRO) 43 43 #include "PlatformRefPtrCairo.h" 44 namespace WebCore { 45 class ContextShadow; 46 } 44 47 typedef struct _cairo PlatformGraphicsContext; 45 48 #elif PLATFORM(OPENVG) … … 299 302 #if PLATFORM(CAIRO) 300 303 float getAlpha(); 301 void applyPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, FloatRect& shadowRect, float radius);302 PlatformRefPtr<cairo_surface_t> createShadowMask(PassOwnPtr<ImageBuffer>, FloatRect&, float radius);303 304 static void calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& radius, const FloatRect& sourceRect, const FloatSize& shadowOffset, float shadowBlur);305 void drawTiledShadow(const IntRect& rect, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius, ColorSpace colorSpace);306 304 #endif 307 305 … … 404 402 QPen pen(); 405 403 static QPainter::CompositionMode toQtCompositionMode(CompositeOperator op); 404 #endif 405 406 #if PLATFORM(QT) || PLATFORM(CAIRO) 406 407 ContextShadow* contextShadow(); 407 408 #endif -
trunk/WebCore/platform/graphics/cairo/FontCairo.cpp
r66607 r69681 32 32 33 33 #include "AffineTransform.h" 34 #include "CairoUtilities.h" 35 #include "ContextShadow.h" 34 36 #include "GlyphBuffer.h" 35 37 #include "Gradient.h" … … 39 41 #include "SimpleFontData.h" 40 42 41 #define SYNTHETIC_OBLIQUE_ANGLE 14 43 namespace WebCore { 42 44 43 namespace WebCore { 45 static void prepareContextForGlyphDrawing(cairo_t* context, const SimpleFontData* font, const FloatPoint& point) 46 { 47 static const float syntheticObliqueSkew = -tanf(14 * acosf(0) / 90); 48 cairo_set_scaled_font(context, font->platformData().scaledFont()); 49 if (font->platformData().syntheticOblique()) { 50 cairo_matrix_t mat = {1, 0, syntheticObliqueSkew, 1, point.x(), point.y()}; 51 cairo_transform(context, &mat); 52 } else 53 cairo_translate(context, point.x(), point.y()); 54 } 55 56 static void drawGlyphsToContext(cairo_t* context, const SimpleFontData* font, GlyphBufferGlyph* glyphs, int numGlyphs) 57 { 58 cairo_show_glyphs(context, glyphs, numGlyphs); 59 if (font->syntheticBoldOffset()) { 60 // We could use cairo_save/cairo_restore here, but two translations are likely faster. 61 cairo_translate(context, font->syntheticBoldOffset(), 0); 62 cairo_show_glyphs(context, glyphs, numGlyphs); 63 cairo_translate(context, -font->syntheticBoldOffset(), 0); 64 } 65 } 66 67 static void drawGlyphsShadow(GraphicsContext* graphicsContext, cairo_t* context, const FloatPoint& point, const SimpleFontData* font, GlyphBufferGlyph* glyphs, int numGlyphs) 68 { 69 ContextShadow* shadow = graphicsContext->contextShadow(); 70 ASSERT(shadow); 71 72 if (!(graphicsContext->textDrawingMode() & cTextFill) || shadow->m_type == ContextShadow::NoShadow) 73 return; 74 75 if (shadow->m_type == ContextShadow::SolidShadow) { 76 // Optimize non-blurry shadows, by just drawing text without the ContextShadow. 77 cairo_save(context); 78 cairo_translate(context, shadow->m_offset.width(), shadow->m_offset.height()); 79 setSourceRGBAFromColor(context, shadow->m_color); 80 prepareContextForGlyphDrawing(context, font, point); 81 cairo_show_glyphs(context, glyphs, numGlyphs); 82 cairo_restore(context); 83 return; 84 } 85 86 cairo_text_extents_t extents; 87 cairo_scaled_font_glyph_extents(font->platformData().scaledFont(), glyphs, numGlyphs, &extents); 88 FloatRect fontExtentsRect(point.x(), point.y() - extents.height, extents.width, extents.height); 89 cairo_t* shadowContext = shadow->beginShadowLayer(context, fontExtentsRect); 90 if (shadowContext) { 91 prepareContextForGlyphDrawing(shadowContext, font, point); 92 drawGlyphsToContext(shadowContext, font, glyphs, numGlyphs); 93 shadow->endShadowLayer(context); 94 } 95 } 44 96 45 97 void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, 46 98 int from, int numGlyphs, const FloatPoint& point) const 47 99 { 48 cairo_t* cr = context->platformContext();49 cairo_save(cr);50 51 cairo_set_scaled_font(cr, font->platformData().scaledFont());52 53 100 GlyphBufferGlyph* glyphs = (GlyphBufferGlyph*)glyphBuffer.glyphs(from); 54 101 … … 60 107 } 61 108 62 Color fillColor = context->fillColor(); 109 cairo_t* cr = context->platformContext(); 110 drawGlyphsShadow(context, cr, point, font, glyphs, numGlyphs); 63 111 64 // Synthetic Oblique 65 if(font->platformData().syntheticOblique()) { 66 cairo_matrix_t mat = {1, 0, -tanf(SYNTHETIC_OBLIQUE_ANGLE * acosf(0) / 90), 1, point.x(), point.y()}; 67 cairo_transform(cr, &mat); 68 } else { 69 cairo_translate(cr, point.x(), point.y()); 70 } 71 72 // Text shadow, inspired by FontMac 73 FloatSize shadowOffset; 74 float shadowBlur = 0; 75 Color shadowColor; 76 bool hasShadow = context->textDrawingMode() & cTextFill 77 && context->getShadow(shadowOffset, shadowBlur, shadowColor); 78 79 // TODO: Blur support 80 if (hasShadow) { 81 // Disable graphics context shadows (not yet implemented) and paint them manually 82 context->clearShadow(); 83 Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255); 84 cairo_save(cr); 85 86 float red, green, blue, alpha; 87 shadowFillColor.getRGBA(red, green, blue, alpha); 88 cairo_set_source_rgba(cr, red, green, blue, alpha); 89 90 #if ENABLE(FILTERS) 91 cairo_text_extents_t extents; 92 cairo_scaled_font_glyph_extents(font->platformData().scaledFont(), glyphs, numGlyphs, &extents); 93 94 FloatRect rect(FloatPoint(), FloatSize(extents.width, extents.height)); 95 IntSize shadowBufferSize; 96 FloatRect shadowRect; 97 float radius = 0; 98 context->calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowOffset, shadowBlur); 99 100 // Draw shadow into a new ImageBuffer 101 OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize); 102 GraphicsContext* shadowContext = shadowBuffer->context(); 103 cairo_t* shadowCr = shadowContext->platformContext(); 104 105 cairo_translate(shadowCr, radius, extents.height + radius); 106 107 cairo_set_scaled_font(shadowCr, font->platformData().scaledFont()); 108 cairo_show_glyphs(shadowCr, glyphs, numGlyphs); 109 if (font->syntheticBoldOffset()) { 110 cairo_save(shadowCr); 111 cairo_translate(shadowCr, font->syntheticBoldOffset(), 0); 112 cairo_show_glyphs(shadowCr, glyphs, numGlyphs); 113 cairo_restore(shadowCr); 114 } 115 cairo_translate(cr, 0.0, -extents.height); 116 context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius); 117 #else 118 cairo_translate(cr, shadowOffset.width(), shadowOffset.height()); 119 cairo_show_glyphs(cr, glyphs, numGlyphs); 120 if (font->syntheticBoldOffset()) { 121 cairo_save(cr); 122 cairo_translate(cr, font->syntheticBoldOffset(), 0); 123 cairo_show_glyphs(cr, glyphs, numGlyphs); 124 cairo_restore(cr); 125 } 126 #endif 127 128 cairo_restore(cr); 129 } 130 112 cairo_save(cr); 113 prepareContextForGlyphDrawing(cr, font, point); 131 114 if (context->textDrawingMode() & cTextFill) { 132 115 if (context->fillGradient()) { … … 149 132 } else { 150 133 float red, green, blue, alpha; 151 fillColor.getRGBA(red, green, blue, alpha);134 context->fillColor().getRGBA(red, green, blue, alpha); 152 135 cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha()); 153 136 } 154 cairo_show_glyphs(cr, glyphs, numGlyphs); 155 if (font->syntheticBoldOffset()) { 156 cairo_save(cr); 157 cairo_translate(cr, font->syntheticBoldOffset(), 0); 158 cairo_show_glyphs(cr, glyphs, numGlyphs); 159 cairo_restore(cr); 160 } 137 drawGlyphsToContext(cr, font, glyphs, numGlyphs); 161 138 } 162 139 … … 184 161 cairo_pattern_destroy(pattern); 185 162 } else { 186 Color strokeColor = context->strokeColor();187 163 float red, green, blue, alpha; 188 strokeColor.getRGBA(red, green, blue, alpha);164 context->strokeColor().getRGBA(red, green, blue, alpha); 189 165 cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha()); 190 } 166 } 191 167 cairo_glyph_path(cr, glyphs, numGlyphs); 192 168 cairo_set_line_width(cr, context->strokeThickness()); … … 194 170 } 195 171 196 // Re-enable the platform shadow we disabled earlier197 if (hasShadow)198 context->setShadow(shadowOffset, shadowBlur, shadowColor, DeviceColorSpace);199 200 172 cairo_restore(cr); 201 173 } -
trunk/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
r69517 r69681 37 37 #include "CairoPath.h" 38 38 #include "CairoUtilities.h" 39 #include " FEGaussianBlur.h"39 #include "ContextShadow.h" 40 40 #include "FloatRect.h" 41 41 #include "Font.h" 42 #include "GraphicsContextPlatformPrivateCairo.h" 43 #include "GraphicsContextPrivate.h" 42 44 #include "OwnPtrCairo.h" 43 #include "ImageBuffer.h"44 #include "ImageBufferFilter.h"45 45 #include "IntRect.h" 46 46 #include "NotImplemented.h" … … 49 49 #include "PlatformRefPtrCairo.h" 50 50 #include "SimpleFontData.h" 51 #include "SourceGraphic.h"52 53 51 #include <cairo.h> 54 52 #include <math.h> … … 62 60 #include <cairo-win32.h> 63 61 #endif 64 #include "GraphicsContextPlatformPrivateCairo.h"65 #include "GraphicsContextPrivate.h"66 62 67 63 using namespace std; … … 141 137 } 142 138 143 void GraphicsContext::calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& radius, const FloatRect& sourceRect, const FloatSize& shadowOffset, float shadowBlur) 144 { 145 #if ENABLE(FILTERS) 146 // limit radius to 128 147 radius = min(128.f, max(shadowBlur, 0.f)); 148 149 shadowBufferSize = IntSize(sourceRect.width() + radius * 2, sourceRect.height() + radius * 2); 150 151 // determine dimensions of shadow rect 152 shadowRect = FloatRect(sourceRect.location(), shadowBufferSize); 153 shadowRect.move(shadowOffset.width() - radius, shadowOffset.height() - radius); 154 #endif 155 } 156 157 static inline void drawPathShadow(GraphicsContext* context, GraphicsContextPrivate* gcp, bool fillShadow, bool strokeShadow) 158 { 159 #if ENABLE(FILTERS) 160 FloatSize shadowOffset; 161 float shadowBlur; 162 Color shadowColor; 163 if (!context->getShadow(shadowOffset, shadowBlur, shadowColor)) 164 return; 165 166 // Calculate filter values to create appropriate shadow. 167 cairo_t* cr = context->platformContext(); 168 double x0, x1, y0, y1; 169 if (strokeShadow) 170 cairo_stroke_extents(cr, &x0, &y0, &x1, &y1); 171 else 172 cairo_fill_extents(cr, &x0, &y0, &x1, &y1); 173 FloatRect rect(x0, y0, x1 - x0, y1 - y0); 174 175 IntSize shadowBufferSize; 176 FloatRect shadowRect; 177 float radius = 0; 178 GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowOffset, shadowBlur); 179 180 cairo_clip_extents(cr, &x0, &y0, &x1, &y1); 181 FloatRect clipRect(x0, y0, x1 - x0, y1 - y0); 182 183 FloatPoint rectLocation = shadowRect.location(); 184 185 // Reduce the shadow rect using the clip area. 186 if (!clipRect.contains(shadowRect)) { 187 shadowRect.intersect(clipRect); 188 if (shadowRect.isEmpty()) 189 return; 190 shadowRect.inflate(radius); 191 shadowBufferSize = IntSize(shadowRect.width(), shadowRect.height()); 192 } 193 194 shadowOffset = rectLocation - shadowRect.location(); 195 196 // Create suitably-sized ImageBuffer to hold the shadow. 197 OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize); 198 199 // Draw shadow into a new ImageBuffer. 200 cairo_t* shadowContext = shadowBuffer->context()->platformContext(); 201 copyContextProperties(cr, shadowContext); 202 cairo_translate(shadowContext, -rect.x() + radius + shadowOffset.width(), -rect.y() + radius + shadowOffset.height()); 203 cairo_new_path(shadowContext); 204 OwnPtr<cairo_path_t> path(cairo_copy_path(cr)); 205 cairo_append_path(shadowContext, path.get()); 206 207 if (fillShadow) 208 setPlatformFill(context, shadowContext, gcp); 209 if (strokeShadow) 210 setPlatformStroke(context, shadowContext, gcp); 211 212 context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius); 213 #endif 139 enum PathDrawingStyle { 140 Fill = 1, 141 Stroke = 2, 142 FillAndStroke = Fill + Stroke 143 }; 144 145 static inline void drawPathShadow(GraphicsContext* context, GraphicsContextPrivate* contextPrivate, PathDrawingStyle drawingStyle) 146 { 147 ContextShadow* shadow = context->contextShadow(); 148 ASSERT(shadow); 149 if (shadow->m_type == ContextShadow::NoShadow) 150 return; 151 152 // Calculate the extents of the rendered solid paths. 153 cairo_t* cairoContext = context->platformContext(); 154 cairo_path_t* path = cairo_copy_path(cairoContext); 155 156 FloatRect solidFigureExtents; 157 double x0 = 0; 158 double x1 = 0; 159 double y0 = 0; 160 double y1 = 0; 161 if (drawingStyle & Stroke) { 162 cairo_stroke_extents(cairoContext, &x0, &y0, &x1, &y1); 163 solidFigureExtents = FloatRect(x0, y0, x1 - x0, y1 - y0); 164 } 165 if (drawingStyle & Fill) { 166 cairo_fill_extents(cairoContext, &x0, &y0, &x1, &y1); 167 FloatRect fillExtents(x0, y0, x1 - x0, y1 - y0); 168 solidFigureExtents.unite(fillExtents); 169 } 170 171 cairo_t* shadowContext = shadow->beginShadowLayer(cairoContext, solidFigureExtents); 172 if (!shadowContext) 173 return; 174 175 // It's important to copy the context properties to the new shadow 176 // context to preserve things such as the fill rule and stroke width. 177 copyContextProperties(cairoContext, shadowContext); 178 cairo_append_path(shadowContext, path); 179 180 if (drawingStyle & Fill) 181 setPlatformFill(context, shadowContext, contextPrivate); 182 if (drawingStyle & Stroke) 183 setPlatformStroke(context, shadowContext, contextPrivate); 184 185 shadow->endShadowLayer(cairoContext); 214 186 } 215 187 … … 217 189 { 218 190 cairo_set_fill_rule(cairoContext, context->fillRule() == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING); 219 drawPathShadow(context, gcp, true, false);191 drawPathShadow(context, gcp, Fill); 220 192 221 193 setPlatformFill(context, cairoContext, gcp); … … 225 197 static void strokeCurrentCairoPath(GraphicsContext* context, GraphicsContextPrivate* gcp, cairo_t* cairoContext) 226 198 { 227 drawPathShadow(context, gcp, false, true);199 drawPathShadow(context, gcp, Stroke); 228 200 setPlatformStroke(context, cairoContext, gcp); 229 201 cairo_new_path(cairoContext); … … 262 234 cairo_save(m_data->cr); 263 235 m_data->save(); 236 m_data->shadowStack.append(m_data->shadow); 264 237 } 265 238 … … 268 241 cairo_restore(m_data->cr); 269 242 m_data->restore(); 243 244 if (m_data->shadowStack.isEmpty()) 245 m_data->shadow = ContextShadow(); 246 else { 247 m_data->shadow = m_data->shadowStack.last(); 248 m_data->shadowStack.removeLast(); 249 } 270 250 } 271 251 … … 583 563 584 564 cairo_set_fill_rule(cr, fillRule() == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING); 585 drawPathShadow(this, m_common, true, true);565 drawPathShadow(this, m_common, FillAndStroke); 586 566 587 567 setPlatformFill(this, cr, m_common); … … 602 582 } 603 583 604 static void drawBorderlessRectShadow(GraphicsContext* context, const FloatRect& rect, const Color& rectColor) 605 { 606 #if ENABLE(FILTERS) 607 FloatSize shadowOffset; 608 float shadowBlur; 609 Color shadowColor; 610 if (!context->getShadow(shadowOffset, shadowBlur, shadowColor)) 611 return; 612 613 IntSize shadowBufferSize; 614 FloatRect shadowRect; 615 float radius = 0; 616 GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowOffset, shadowBlur); 617 618 // Draw shadow into a new ImageBuffer 619 OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize); 620 GraphicsContext* shadowContext = shadowBuffer->context(); 621 shadowContext->fillRect(FloatRect(FloatPoint(radius, radius), rect.size()), rectColor, DeviceColorSpace); 622 623 context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius); 624 #endif 625 } 626 627 void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace colorSpace) 628 { 629 if (paintingDisabled()) 630 return; 631 632 drawBorderlessRectShadow(this, rect, color); 584 void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorSpace) 585 { 586 if (paintingDisabled()) 587 return; 588 589 if (m_data->hasShadow()) 590 m_data->shadow.drawRectShadow(this, enclosingIntRect(rect)); 591 633 592 if (color.alpha()) 634 593 fillRectSourceOver(m_data->cr, rect, color); … … 900 859 } 901 860 902 void GraphicsContext::setPlatformShadow(FloatSize const& size, float, Color const&, ColorSpace) 903 { 904 // Cairo doesn't support shadows natively, they are drawn manually in the draw* 905 // functions 906 861 void GraphicsContext::setPlatformShadow(FloatSize const& size, float blur, Color const& color, ColorSpace) 862 { 863 // Cairo doesn't support shadows natively, they are drawn manually in the draw* functions 907 864 if (m_common->state.shadowsIgnoreTransforms) { 908 865 // Meaning that this graphics context is associated with a CanvasRenderingContext 909 866 // We flip the height since CG and HTML5 Canvas have opposite Y axis 910 867 m_common->state.shadowOffset = FloatSize(size.width(), -size.height()); 911 } 912 } 913 914 void GraphicsContext::applyPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, FloatRect& shadowRect, float radius) 915 { 916 #if ENABLE(FILTERS) 917 setColor(m_data->cr, shadowColor); 918 PlatformRefPtr<cairo_surface_t> shadowMask(createShadowMask(buffer, shadowRect, radius)); 919 cairo_mask_surface(m_data->cr, shadowMask.get(), shadowRect.x(), shadowRect.y()); 920 #endif 921 } 922 923 PlatformRefPtr<cairo_surface_t> GraphicsContext::createShadowMask(PassOwnPtr<ImageBuffer> buffer, FloatRect& shadowRect, float radius) 924 { 925 #if ENABLE(FILTERS) 926 if (!radius) 927 return buffer->m_data.m_surface; 928 929 FloatPoint blurRadius = FloatPoint(radius, radius); 930 float stdDeviation = FEGaussianBlur::calculateStdDeviation(radius); 931 if (!stdDeviation) 932 return buffer->m_data.m_surface; 933 934 // create filter 935 IntRect filterRegion = IntRect(IntPoint(), roundedIntSize(shadowRect.size())); 936 RefPtr<Filter> filter = ImageBufferFilter::create(filterRegion); 937 filter->setSourceImage(buffer); 938 RefPtr<FilterEffect> source = SourceGraphic::create(); 939 source->setIsAlphaImage(true); 940 RefPtr<FilterEffect> blur = FEGaussianBlur::create(stdDeviation, stdDeviation); 941 blur->setMaxEffectRect(filterRegion); 942 FilterEffectVector& inputEffects = blur->inputEffects(); 943 inputEffects.append(source.get()); 944 blur->apply(filter.get()); 945 946 // Calculate shadow region for context 947 shadowRect.move(blur->absolutePaintRect().location().x(), blur->absolutePaintRect().location().y()); 948 shadowRect.setSize(blur->absolutePaintRect().size()); 949 return blur->resultImage()->m_data.m_surface; 950 #endif 951 } 952 868 m_data->shadow = ContextShadow(color, blur, FloatSize(size.width(), -size.height())); 869 } else 870 m_data->shadow = ContextShadow(color, blur, FloatSize(size.width(), size.height())); 871 } 872 873 ContextShadow* GraphicsContext::contextShadow() 874 { 875 return &m_data->shadow; 876 } 953 877 954 878 void GraphicsContext::clearPlatformShadow() 955 879 { 956 notImplemented();880 m_data->shadow.clear(); 957 881 } 958 882 … … 1187 1111 } 1188 1112 1189 /*1190 This function uses tiling to improve the performance of the shadow1191 drawing of rounded rectangles. The code basically does the following1192 steps:1193 1194 1. Calculate the minimum rectangle size required to create the1195 tiles1196 1197 2. If that size is smaller than the real rectangle render the new1198 small rectangle and its shadow in a new surface, in other case1199 render the shadow of the real rectangle in the destination1200 surface.1201 1202 3. Calculate the sizes and positions of the tiles and their1203 destinations and use drawPattern to render the final shadow. The1204 code divides the rendering in 8 tiles:1205 1206 1 | 2 | 31207 -----------1208 4 | | 51209 -----------1210 6 | 7 | 81211 1212 The corners are directly copied from the small rectangle to the1213 real one and the side tiles are 1 pixel width, we use them as1214 1215 tiles to cover the destination side. The corner tiles are bigger1216 than just the side of the rounded corner, we need to increase it1217 because the modifications caused by the corner over the blur1218 effect. We fill the central part with solid color to complete the1219 shadow.1220 */1221 void GraphicsContext::drawTiledShadow(const IntRect& rect, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius, ColorSpace colorSpace)1222 {1223 #if ENABLE(FILTERS)1224 FloatSize shadowSize;1225 float shadowBlur;1226 Color shadowColor;1227 if (!getShadow(shadowSize, shadowBlur, shadowColor))1228 return;1229 1230 // Calculate filter values to create appropriate shadow.1231 cairo_t* cr = m_data->cr;1232 1233 IntSize shadowBufferSize;1234 FloatRect shadowRect;1235 float blurRadius = 0;1236 GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, blurRadius, rect, shadowSize, shadowBlur);1237 1238 // Size of the tiling side.1239 int sideTileWidth = 1;1240 float radiusTwice = blurRadius * 2;1241 1242 // Find the extra space needed from the curve of the corners.1243 int extraWidthFromCornerRadii = radiusTwice + max(topLeftRadius.width(), bottomLeftRadius.width()) +1244 radiusTwice + max(topRightRadius.width(), bottomRightRadius.width());1245 int extraHeightFromCornerRadii = radiusTwice + max(topLeftRadius.height(), topRightRadius.height()) +1246 radiusTwice + max(bottomLeftRadius.height(), bottomRightRadius.height());1247 1248 // The length of a side of the buffer is the enough space for four blur radii,1249 // the radii of the corners, and then 1 pixel to draw the side tiles.1250 IntSize smallBufferSize = IntSize(sideTileWidth + extraWidthFromCornerRadii,1251 sideTileWidth + extraHeightFromCornerRadii);1252 1253 if ((smallBufferSize.width() > shadowBufferSize.width()) || (smallBufferSize.height() > shadowBufferSize.height()) || (blurRadius <= 0)) {1254 // Create suitably-sized ImageBuffer to hold the shadow.1255 OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize);1256 if (!shadowBuffer)1257 return;1258 1259 // Draw shadow into a new ImageBuffer.1260 cairo_t* shadowContext = shadowBuffer->context()->platformContext();1261 copyContextProperties(cr, shadowContext);1262 cairo_translate(shadowContext, -rect.x() + blurRadius, -rect.y() + blurRadius);1263 cairo_new_path(shadowContext);1264 OwnPtr<cairo_path_t> path(cairo_copy_path(cr));1265 cairo_append_path(shadowContext, path.get());1266 1267 setPlatformFill(this, shadowContext, m_common);1268 1269 applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, blurRadius);1270 1271 return;1272 }1273 1274 OwnPtr<ImageBuffer> smallBuffer = ImageBuffer::create(smallBufferSize);1275 if (!smallBuffer)1276 return;1277 1278 FloatRect smallRect = FloatRect(blurRadius, blurRadius, smallBufferSize.width() - radiusTwice, smallBufferSize.height() - radiusTwice);1279 1280 // Draw shadow into a new ImageBuffer.1281 cairo_t* smallBufferContext = smallBuffer->context()->platformContext();1282 copyContextProperties(cr, smallBufferContext);1283 1284 Path path;1285 path.addRoundedRect(smallRect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);1286 appendWebCorePathToCairoContext(smallBuffer->context()->platformContext(), path);1287 setPlatformFill(this, smallBufferContext, m_common);1288 1289 OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(smallBufferSize);1290 if (!shadowBuffer)1291 return;1292 1293 smallRect.setSize(smallBufferSize);1294 1295 PlatformRefPtr<cairo_surface_t> shadowMask(createShadowMask(smallBuffer.release(), smallRect, blurRadius));1296 1297 cairo_t* shadowContext = shadowBuffer->context()->platformContext();1298 setColor(shadowContext, shadowColor);1299 cairo_mask_surface(shadowContext, shadowMask.get(), 0, 0);1300 1301 // Fill the internal part of the shadow.1302 shadowRect.inflate(-radiusTwice);1303 if (!shadowRect.isEmpty()) {1304 cairo_save(cr);1305 path.clear();1306 path.addRoundedRect(shadowRect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);1307 appendWebCorePathToCairoContext(cr, path);1308 setColor(cr, shadowColor);1309 cairo_fill(cr);1310 cairo_restore(cr);1311 }1312 shadowRect.inflate(radiusTwice);1313 1314 // Draw top side.1315 FloatRect tileRect = FloatRect(radiusTwice + topLeftRadius.width(), 0, sideTileWidth, radiusTwice);1316 FloatRect destRect = tileRect;1317 destRect.move(shadowRect.x(), shadowRect.y());1318 destRect.setWidth(shadowRect.width() - topLeftRadius.width() - topRightRadius.width() - blurRadius * 4);1319 FloatPoint phase = getPhase(destRect, tileRect);1320 AffineTransform patternTransform;1321 patternTransform.makeIdentity();1322 shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);1323 1324 // Draw the bottom side.1325 tileRect = FloatRect(radiusTwice + bottomLeftRadius.width(), smallBufferSize.height() - radiusTwice, sideTileWidth, radiusTwice);1326 destRect = tileRect;1327 destRect.move(shadowRect.x(), shadowRect.y() + radiusTwice + rect.height() - smallBufferSize.height());1328 destRect.setWidth(shadowRect.width() - bottomLeftRadius.width() - bottomRightRadius.width() - blurRadius * 4);1329 phase = getPhase(destRect, tileRect);1330 shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);1331 1332 // Draw the right side.1333 tileRect = FloatRect(smallBufferSize.width() - radiusTwice, radiusTwice + topRightRadius.height(), radiusTwice, sideTileWidth);1334 destRect = tileRect;1335 destRect.move(shadowRect.x() + radiusTwice + rect.width() - smallBufferSize.width(), shadowRect.y());1336 destRect.setHeight(shadowRect.height() - topRightRadius.height() - bottomRightRadius.height() - blurRadius * 4);1337 phase = getPhase(destRect, tileRect);1338 shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);1339 1340 // Draw the left side.1341 tileRect = FloatRect(0, radiusTwice + topLeftRadius.height(), radiusTwice, sideTileWidth);1342 destRect = tileRect;1343 destRect.move(shadowRect.x(), shadowRect.y());1344 destRect.setHeight(shadowRect.height() - topLeftRadius.height() - bottomLeftRadius.height() - blurRadius * 4);1345 phase = FloatPoint(destRect.x() - tileRect.x(), destRect.y() - tileRect.y());1346 shadowBuffer->drawPattern(this, tileRect, patternTransform,1347 phase, colorSpace, CompositeSourceOver, destRect);1348 1349 // Draw the top left corner.1350 tileRect = FloatRect(0, 0, radiusTwice + topLeftRadius.width(), radiusTwice + topLeftRadius.height());1351 destRect = tileRect;1352 destRect.move(shadowRect.x(), shadowRect.y());1353 phase = getPhase(destRect, tileRect);1354 shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);1355 1356 // Draw the top right corner.1357 tileRect = FloatRect(smallBufferSize.width() - radiusTwice - topRightRadius.width(), 0, radiusTwice + topRightRadius.width(), radiusTwice + topRightRadius.height());1358 destRect = tileRect;1359 destRect.move(shadowRect.x() + rect.width() - smallBufferSize.width() + radiusTwice, shadowRect.y());1360 phase = getPhase(destRect, tileRect);1361 shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);1362 1363 // Draw the bottom right corner.1364 tileRect = FloatRect(smallBufferSize.width() - radiusTwice - bottomRightRadius.width(), smallBufferSize.height() - radiusTwice - bottomRightRadius.height(), radiusTwice + bottomRightRadius.width(), radiusTwice + bottomRightRadius.height());1365 destRect = tileRect;1366 destRect.move(shadowRect.x() + rect.width() - smallBufferSize.width() + radiusTwice, shadowRect.y() + rect.height() - smallBufferSize.height() + radiusTwice);1367 phase = getPhase(destRect, tileRect);1368 shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);1369 1370 // Draw the bottom left corner.1371 tileRect = FloatRect(0, smallBufferSize.height() - radiusTwice - bottomLeftRadius.height(), radiusTwice + bottomLeftRadius.width(), radiusTwice + bottomLeftRadius.height());1372 destRect = tileRect;1373 destRect.move(shadowRect.x(), shadowRect.y() + rect.height() - smallBufferSize.height() + radiusTwice);1374 phase = getPhase(destRect, tileRect);1375 shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);1376 #endif1377 }1378 1379 1113 void GraphicsContext::fillRoundedRect(const IntRect& r, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace colorSpace) 1380 1114 { 1381 1115 if (paintingDisabled()) 1382 1116 return; 1117 1118 if (m_data->hasShadow()) 1119 m_data->shadow.drawRectShadow(this, r, topLeft, topRight, bottomLeft, bottomRight); 1383 1120 1384 1121 cairo_t* cr = m_data->cr; … … 1388 1125 appendWebCorePathToCairoContext(cr, path); 1389 1126 setColor(cr, color); 1390 drawPathShadow(this, m_common, true, false);1391 1127 cairo_fill(cr); 1392 1128 cairo_restore(cr); -
trunk/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
r66047 r69681 99 99 CairoPath m_pendingPath; 100 100 101 ContextShadow shadow; 102 Vector<ContextShadow> shadowStack; 103 bool hasShadow() const { return shadow.m_type != ContextShadow::NoShadow; } 104 101 105 #if PLATFORM(GTK) 102 106 GdkEventExpose* expose; -
trunk/WebCore/platform/graphics/cairo/ImageCairo.cpp
r69015 r69681 34 34 #include "CairoUtilities.h" 35 35 #include "Color.h" 36 #include "ContextShadow.h" 36 37 #include "FloatRect.h" 37 38 #include "PlatformRefPtrCairo.h" … … 135 136 cairo_pattern_set_matrix(pattern, &matrix); 136 137 137 // Draw the shadow 138 #if ENABLE(FILTERS) 139 FloatSize shadowOffset; 140 float shadowBlur; 141 Color shadowColor; 142 if (context->getShadow(shadowOffset, shadowBlur, shadowColor)) { 143 IntSize shadowBufferSize; 144 FloatRect shadowRect; 145 float radius = 0; 146 context->calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, dstRect, shadowOffset, shadowBlur); 147 shadowColor = colorWithOverrideAlpha(shadowColor.rgb(), (shadowColor.alpha() * context->getAlpha()) / 255.f); 148 149 //draw shadow into a new ImageBuffer 150 OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize); 151 cairo_t* shadowContext = shadowBuffer->context()->platformContext(); 152 cairo_set_source(shadowContext, pattern); 153 cairo_translate(shadowContext, -dstRect.x(), -dstRect.y()); 154 cairo_rectangle(shadowContext, 0, 0, dstRect.width(), dstRect.height()); 155 cairo_fill(shadowContext); 156 157 context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius); 138 ContextShadow* shadow = context->contextShadow(); 139 ASSERT(shadow); 140 if (shadow->m_type != ContextShadow::NoShadow) { 141 cairo_t* shadowContext = shadow->beginShadowLayer(cr, dstRect); 142 if (shadowContext) { 143 cairo_translate(shadowContext, dstRect.x(), dstRect.y()); 144 cairo_set_source(shadowContext, pattern); 145 cairo_rectangle(shadowContext, 0, 0, dstRect.width(), dstRect.height()); 146 cairo_fill(shadowContext); 147 shadow->endShadowLayer(cr); 148 } 158 149 } 159 #endif160 150 161 151 // Draw the image.
Note: See TracChangeset
for help on using the changeset viewer.