Changeset 228776 in webkit
- Timestamp:
- Feb 20, 2018 2:52:16 AM (6 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r228771 r228776 1 2018-02-20 Zan Dobersek <zdobersek@igalia.com> 2 3 [Cairo] Leverage ShadowBlur without using scratch buffer, target GraphicsContext 4 https://bugs.webkit.org/show_bug.cgi?id=182958 5 6 Reviewed by Carlos Garcia Campos. 7 8 To allow ShadowBlur usage in different threads, avoid the ShadowBlur 9 class using the scratch buffer internally. The current implementation of 10 that scratch buffer is not thread-safe and its usage in such conditions 11 can lead to crashes. 12 13 Instead, the new methods use a temporary ImageBuffer object for drawing. 14 This does negate the efficiency of possibly reusing the scratch buffer, 15 but at this point that is not yet the priority. This only affects ports 16 using Cairo for drawing. 17 18 The added methods don't require a target GraphicsContext object to be 19 passed in, instead they accept buffer draw callbacks that are invoked 20 with the temporary ImageBuffer object containing the rasterized shadow, 21 as well as position and size parameters. The CTM and clip bounds values 22 also have to be passed in manually. In CairoOperations.cpp, the provided 23 callbacks invoke commands that are equivalent in effect to those that 24 would otherwise be invoked on the target GraphicsContext object in the 25 ShadowBlur class. 26 27 For now, this approach has to avoid the tiling-based drawing of the 28 rectangular shadows in drawRectShadow() and inset shadows in 29 drawInsetShadow(), and instead stick to the non-tiling fallback. While 30 only affecting Cairo-using ports, with some refactoring it should be 31 possible to again leverage the tiling-based approach as well. 32 33 The beginShadowLayer() and endShadowLayer() functions, which are only 34 used in CairoOperations.cpp, are replaced with the drawShadowLayer() 35 method. This one accepts an additional callback that allows the caller 36 to explicitly draw the shadow shape using the provided shadowing 37 GraphicsContext object. As with the other two new methods, a temporary 38 ImageBuffer object is used, and the buffer draw callback is invoked to 39 allow caller to properly handle the shadowing output. 40 41 In CairoOperations.cpp, the new ShadowBlur methods are exercised, with 42 direct Cairo operation invocation replacing the GraphicsContext calls 43 otherwise done through ShadowBlur. ShadowState object now also has to 44 track the global alpha and the global composite operator values so that 45 it can properly rasterize the resulting shadow into the final image. 46 47 No new tests -- no change in behavior. 48 49 * platform/graphics/ShadowBlur.cpp: 50 (WebCore::ShadowBlur::adjustBlurRadius): 51 (WebCore::ShadowBlur::calculateLayerBoundingRect): 52 (WebCore::ShadowBlur::drawRectShadow): 53 (WebCore::ShadowBlur::drawInsetShadow): 54 (WebCore::ShadowBlur::drawShadowLayer): 55 (WebCore::ShadowBlur::beginShadowLayer): Deleted. 56 (WebCore::ShadowBlur::endShadowLayer): Deleted. 57 * platform/graphics/ShadowBlur.h: 58 * platform/graphics/cairo/CairoOperations.cpp: 59 (WebCore::Cairo::drawShadowLayerBuffer): 60 (WebCore::Cairo::fillShadowBuffer): 61 (WebCore::Cairo::drawPathShadow): 62 (WebCore::Cairo::drawGlyphsShadow): 63 (WebCore::Cairo::ShadowState::ShadowState): 64 (WebCore::Cairo::fillRect): 65 (WebCore::Cairo::fillRoundedRect): 66 (WebCore::Cairo::fillRectWithRoundedHole): 67 (WebCore::Cairo::drawSurface): 68 * platform/graphics/cairo/CairoOperations.h: 69 Default-initialize FillSource::fillRule to RULE_NONZERO. 70 * platform/graphics/cairo/PlatformContextCairo.h: 71 Drop the ShadowBlur.h include, it's moved to CairoOperations.cpp. 72 * rendering/RenderThemeGtk.cpp: 73 Explicitly include the FloatRoundedRect.h header now that it's not 74 included through the ShadowBlur.h header via PlatformContextCairo.h. 75 1 76 2018-02-20 Sergio Villar Senin <svillar@igalia.com> 2 77 -
trunk/Source/WebCore/platform/graphics/ShadowBlur.cpp
r227051 r228776 360 360 } 361 361 362 void ShadowBlur::adjustBlurRadius(GraphicsContext& context) 363 { 364 if (!m_shadowsIgnoreTransforms) 365 return; 366 367 AffineTransform transform = context.getCTM(); 368 m_blurRadius.scale(1 / static_cast<float>(transform.xScale()), 1 / static_cast<float>(transform.yScale())); 362 void ShadowBlur::adjustBlurRadius(const AffineTransform& transform) 363 { 364 if (m_shadowsIgnoreTransforms) 365 m_blurRadius.scale(1 / static_cast<float>(transform.xScale()), 1 / static_cast<float>(transform.yScale())); 369 366 } 370 367 … … 383 380 } 384 381 385 IntSize ShadowBlur::calculateLayerBoundingRect( GraphicsContext& context, const FloatRect& shadowedRect, const IntRect& clipRect)382 IntSize ShadowBlur::calculateLayerBoundingRect(const AffineTransform& transform, const FloatRect& shadowedRect, const IntRect& clipRect) 386 383 { 387 384 IntSize edgeSize = blurredEdgeSize(); … … 391 388 IntSize inflation; 392 389 393 const AffineTransform transform = context.getCTM();394 390 if (m_shadowsIgnoreTransforms && !transform.isIdentity()) { 395 391 FloatQuad transformedPolygon = transform.mapQuad(FloatQuad(shadowedRect)); … … 498 494 void ShadowBlur::drawRectShadow(GraphicsContext& graphicsContext, const FloatRoundedRect& shadowedRect) 499 495 { 500 IntSize layerSize = calculateLayerBoundingRect(graphicsContext , shadowedRect.rect(), graphicsContext.clipBounds());496 IntSize layerSize = calculateLayerBoundingRect(graphicsContext.getCTM(), shadowedRect.rect(), graphicsContext.clipBounds()); 501 497 if (layerSize.isEmpty()) 502 498 return; 503 499 504 adjustBlurRadius(graphicsContext );500 adjustBlurRadius(graphicsContext.getCTM()); 505 501 506 502 // drawRectShadowWithTiling does not work with rotations. … … 526 522 void ShadowBlur::drawInsetShadow(GraphicsContext& graphicsContext, const FloatRect& rect, const FloatRoundedRect& holeRect) 527 523 { 528 IntSize layerSize = calculateLayerBoundingRect(graphicsContext , rect, graphicsContext.clipBounds());524 IntSize layerSize = calculateLayerBoundingRect(graphicsContext.getCTM(), rect, graphicsContext.clipBounds()); 529 525 if (layerSize.isEmpty()) 530 526 return; 531 527 532 adjustBlurRadius(graphicsContext );528 adjustBlurRadius(graphicsContext.getCTM()); 533 529 534 530 // drawInsetShadowWithTiling does not work with rotations. … … 550 546 551 547 drawInsetShadowWithTiling(graphicsContext, rect, holeRect, templateSize, edgeSize); 548 } 549 550 void ShadowBlur::drawRectShadow(const AffineTransform& transform, const IntRect& clipBounds, const FloatRoundedRect& shadowedRect, const DrawBufferCallback& drawBuffer) 551 { 552 // FIXME: Try incorporating tile-based rect shadow drawing for the same use case. 553 554 IntSize layerSize = calculateLayerBoundingRect(transform, shadowedRect.rect(), clipBounds); 555 if (layerSize.isEmpty()) 556 return; 557 558 adjustBlurRadius(transform); 559 560 auto layerImage = ImageBuffer::create(layerSize, Unaccelerated, 1); 561 if (!layerImage) 562 return; 563 m_layerImage = layerImage.get(); 564 565 { 566 GraphicsContext& shadowContext = layerImage->context(); 567 GraphicsContextStateSaver stateSaver(shadowContext); 568 shadowContext.translate(m_layerContextTranslation); 569 shadowContext.setFillColor(Color::black); 570 if (shadowedRect.radii().isZero()) 571 shadowContext.fillRect(shadowedRect.rect()); 572 else { 573 Path path; 574 path.addRoundedRect(shadowedRect); 575 shadowContext.fillPath(path); 576 } 577 578 blurShadowBuffer(layerSize); 579 } 580 581 drawBuffer(*layerImage, m_layerOrigin, m_layerSize, m_sourceRect); 582 } 583 584 void ShadowBlur::drawInsetShadow(const AffineTransform& transform, const IntRect& clipBounds, const FloatRect& rect, const FloatRoundedRect& holeRect, const DrawBufferCallback& drawBuffer) 585 { 586 // FIXME: Try incorporating tile-based inset shadow drawing for the same use case. 587 588 IntSize layerSize = calculateLayerBoundingRect(transform, rect, clipBounds); 589 if (layerSize.isEmpty()) 590 return; 591 592 adjustBlurRadius(transform); 593 594 auto layerImage = ImageBuffer::create(layerSize, Unaccelerated, 1); 595 if (!layerImage) 596 return; 597 m_layerImage = layerImage.get(); 598 599 { 600 GraphicsContext& shadowContext = layerImage->context(); 601 GraphicsContextStateSaver stateSaver(shadowContext); 602 shadowContext.translate(m_layerContextTranslation); 603 604 Path path; 605 path.addRect(rect); 606 if (holeRect.radii().isZero()) 607 path.addRect(holeRect.rect()); 608 else 609 path.addRoundedRect(holeRect); 610 611 shadowContext.setFillRule(RULE_EVENODD); 612 shadowContext.setFillColor(Color::black); 613 shadowContext.fillPath(path); 614 615 blurShadowBuffer(layerSize); 616 } 617 618 drawBuffer(*layerImage, m_layerOrigin, m_layerSize, m_sourceRect); 552 619 } 553 620 … … 875 942 } 876 943 877 GraphicsContext* ShadowBlur::beginShadowLayer(GraphicsContext& context, const FloatRect& layerArea) 878 { 879 adjustBlurRadius(context); 880 881 IntSize layerSize = calculateLayerBoundingRect(context, layerArea, context.clipBounds()); 882 944 void ShadowBlur::drawShadowLayer(const AffineTransform& transform, const IntRect& clipBounds, const FloatRect& layerArea, const DrawShadowCallback& drawShadow, const DrawBufferCallback& drawBuffer) 945 { 946 IntSize layerSize = calculateLayerBoundingRect(transform, layerArea, clipBounds); 883 947 if (layerSize.isEmpty()) 884 return nullptr; 885 886 // We reset the scratch buffer values here, because the buffer will no longer contain 887 // data from any previous rectangle or inset shadows drawn via the tiling path. 888 auto& scratchBuffer = ScratchBuffer::singleton(); 889 scratchBuffer.setCachedShadowValues(FloatSize(), Color::black, IntRect(), FloatRoundedRect::Radii(), m_layerSize); 890 m_layerImage = scratchBuffer.getScratchBuffer(layerSize); 891 892 GraphicsContext& shadowContext = m_layerImage->context(); 893 shadowContext.save(); 894 895 // Add a pixel to avoid later edge aliasing when rotated. 896 shadowContext.clearRect(FloatRect(0, 0, m_layerSize.width() + 1, m_layerSize.height() + 1)); 897 898 shadowContext.translate(m_layerContextTranslation); 899 return &shadowContext; 900 } 901 902 void ShadowBlur::endShadowLayer(GraphicsContext& context) 903 { 904 m_layerImage->context().restore(); 948 return; 949 950 adjustBlurRadius(transform); 951 952 auto layerImage = ImageBuffer::create(layerSize, Unaccelerated, 1); 953 if (!layerImage) 954 return; 955 m_layerImage = layerImage.get(); 956 957 { 958 GraphicsContext& shadowContext = layerImage->context(); 959 GraphicsContextStateSaver stateSaver(shadowContext); 960 shadowContext.translate(m_layerContextTranslation); 961 drawShadow(shadowContext); 962 } 905 963 906 964 blurAndColorShadowBuffer(expandedIntSize(m_layerSize)); 907 GraphicsContextStateSaver stateSave(context); 908 909 context.clearShadow(); 910 context.drawImageBuffer(*m_layerImage, FloatRect(roundedIntPoint(m_layerOrigin), m_layerSize), FloatRect(FloatPoint(), m_layerSize), context.compositeOperation()); 911 912 m_layerImage = nullptr; 913 ScratchBuffer::singleton().scheduleScratchBufferPurge(); 965 drawBuffer(*layerImage, m_layerOrigin, m_layerSize, m_sourceRect); 914 966 } 915 967 -
trunk/Source/WebCore/platform/graphics/ShadowBlur.h
r227051 r228776 33 33 #include "FloatRect.h" 34 34 #include "FloatRoundedRect.h" 35 #include <wtf/Function.h> 35 36 #include <wtf/Noncopyable.h> 36 37 … … 60 61 bool shadowsIgnoreTransforms() const { return m_shadowsIgnoreTransforms; } 61 62 62 GraphicsContext* beginShadowLayer(GraphicsContext&, const FloatRect& layerArea);63 void endShadowLayer(GraphicsContext&);64 65 63 void drawRectShadow(GraphicsContext&, const FloatRoundedRect&); 66 64 void drawInsetShadow(GraphicsContext&, const FloatRect&, const FloatRoundedRect& holeRect); 65 66 using DrawBufferCallback = WTF::Function<void(ImageBuffer&, const FloatPoint&, const FloatSize&, const FloatRect&)>; 67 void drawRectShadow(const AffineTransform&, const IntRect&, const FloatRoundedRect&, const DrawBufferCallback&); 68 void drawInsetShadow(const AffineTransform&, const IntRect&, const FloatRect&, const FloatRoundedRect&, const DrawBufferCallback&); 69 70 using DrawShadowCallback = WTF::Function<void(GraphicsContext&)>; 71 void drawShadowLayer(const AffineTransform&, const IntRect&, const FloatRect&, const DrawShadowCallback&, const DrawBufferCallback&); 67 72 68 73 void blurLayerImage(unsigned char*, const IntSize&, int stride); … … 77 82 void drawShadowBuffer(GraphicsContext&); 78 83 79 void adjustBlurRadius( GraphicsContext&);84 void adjustBlurRadius(const AffineTransform&); 80 85 81 86 enum ShadowDirection { … … 84 89 }; 85 90 86 IntSize calculateLayerBoundingRect( GraphicsContext&, const FloatRect& layerArea, const IntRect& clipRect);91 IntSize calculateLayerBoundingRect(const AffineTransform&, const FloatRect& layerArea, const IntRect& clipRect); 87 92 IntSize templateSize(const IntSize& blurredEdgeSize, const FloatRoundedRect::Radii&) const; 88 93 -
trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp
r227292 r228776 42 42 #include "GraphicsContextPlatformPrivateCairo.h" 43 43 #include "Image.h" 44 #include "ImageBuffer.h" 44 45 #include "Path.h" 45 46 #include "PlatformContextCairo.h" 46 47 #include "PlatformPathCairo.h" 48 #include "ShadowBlur.h" 47 49 #include <algorithm> 48 50 #include <cairo.h> … … 174 176 }; 175 177 178 static void drawShadowLayerBuffer(PlatformContextCairo& platformContext, ImageBuffer& layerImage, const FloatPoint& layerOrigin, const FloatSize& layerSize, const ShadowState& shadowState, GraphicsContext& targetContext) 179 { 180 RefPtr<Image> image = layerImage.copyImage(DontCopyBackingStore); 181 if (!image) 182 return; 183 184 if (auto surface = image->nativeImageForCurrentFrame()) { 185 drawNativeImage(platformContext, surface.get(), FloatRect(roundedIntPoint(layerOrigin), layerSize), FloatRect(FloatPoint(), layerSize), 186 shadowState.globalCompositeOperator, BlendModeNormal, ImageOrientation(), 187 InterpolationDefault, shadowState.globalAlpha, ShadowState(), targetContext); 188 } 189 } 190 191 static void fillShadowBuffer(PlatformContextCairo& platformContext, ImageBuffer& layerImage, const FloatPoint& layerOrigin, const FloatSize& layerSize, const FloatRect& sourceRect, const ShadowState& shadowState, GraphicsContext& targetContext) 192 { 193 save(platformContext); 194 195 RefPtr<Image> image = layerImage.copyImage(DontCopyBackingStore); 196 if (image) { 197 if (auto surface = image->nativeImageForCurrentFrame()) 198 clipToImageBuffer(platformContext, surface.get(), FloatRect(layerOrigin, expandedIntSize(layerSize))); 199 } 200 201 FillSource fillSource; 202 fillSource.globalAlpha = shadowState.globalAlpha; 203 fillSource.color = shadowState.color; 204 fillRect(platformContext, FloatRect(layerOrigin, sourceRect.size()), fillSource, ShadowState(), targetContext); 205 206 restore(platformContext); 207 } 208 176 209 static inline void drawPathShadow(PlatformContextCairo& platformContext, const FillSource& fillSource, const StrokeSource& strokeSource, const ShadowState& shadowState, GraphicsContext& targetContext, PathDrawingStyle drawingStyle) 177 210 { … … 201 234 } 202 235 203 GraphicsContext* shadowContext = shadow.beginShadowLayer(targetContext, solidFigureExtents); 204 if (!shadowContext) 205 return; 206 207 cairo_t* cairoShadowContext = shadowContext->platformContext()->cr(); 208 209 // It's important to copy the context properties to the new shadow 210 // context to preserve things such as the fill rule and stroke width. 211 copyContextProperties(cairoContext, cairoShadowContext); 212 213 if (drawingStyle & Fill) { 214 cairo_save(cairoShadowContext); 215 cairo_append_path(cairoShadowContext, path.get()); 216 prepareForFilling(cairoShadowContext, fillSource, NoAdjustment); 217 cairo_fill(cairoShadowContext); 218 cairo_restore(cairoShadowContext); 219 } 220 221 if (drawingStyle & Stroke) { 222 cairo_append_path(cairoShadowContext, path.get()); 223 prepareForStroking(cairoShadowContext, strokeSource, DoNotPreserveAlpha); 224 cairo_stroke(cairoShadowContext); 225 } 226 227 // The original path may still be hanging around on the context and endShadowLayer 228 // will take care of properly creating a path to draw the result shadow. We remove the path 229 // temporarily and then restore it. 230 // See: https://bugs.webkit.org/show_bug.cgi?id=108897 231 cairo_new_path(cairoContext); 232 shadow.endShadowLayer(targetContext); 233 cairo_append_path(cairoContext, path.get()); 236 shadow.drawShadowLayer(State::getCTM(platformContext), State::getClipBounds(platformContext), solidFigureExtents, 237 [cairoContext, drawingStyle, &path, &fillSource, &strokeSource](GraphicsContext& shadowContext) 238 { 239 cairo_t* cairoShadowContext = shadowContext.platformContext()->cr(); 240 241 // It's important to copy the context properties to the new shadow 242 // context to preserve things such as the fill rule and stroke width. 243 copyContextProperties(cairoContext, cairoShadowContext); 244 245 if (drawingStyle & Fill) { 246 cairo_save(cairoShadowContext); 247 cairo_append_path(cairoShadowContext, path.get()); 248 prepareForFilling(cairoShadowContext, fillSource, NoAdjustment); 249 cairo_fill(cairoShadowContext); 250 cairo_restore(cairoShadowContext); 251 } 252 253 if (drawingStyle & Stroke) { 254 cairo_append_path(cairoShadowContext, path.get()); 255 prepareForStroking(cairoShadowContext, strokeSource, DoNotPreserveAlpha); 256 cairo_stroke(cairoShadowContext); 257 } 258 }, 259 [&platformContext, &shadowState, &cairoContext, &path, &targetContext](ImageBuffer& layerImage, const FloatPoint& layerOrigin, const FloatSize& layerSize, const FloatRect&) 260 { 261 // The original path may still be hanging around on the context and endShadowLayer 262 // will take care of properly creating a path to draw the result shadow. We remove the path 263 // temporarily and then restore it. 264 // See: https://bugs.webkit.org/show_bug.cgi?id=108897 265 cairo_new_path(cairoContext); 266 267 drawShadowLayerBuffer(platformContext, layerImage, layerOrigin, layerSize, shadowState, targetContext); 268 269 cairo_append_path(cairoContext, path.get()); 270 }); 234 271 } 235 272 … … 313 350 FloatRect fontExtentsRect(point.x() + extents.x_bearing, point.y() + extents.y_bearing, extents.width, extents.height); 314 351 315 if (GraphicsContext* shadowContext = shadow.beginShadowLayer(targetContext, fontExtentsRect)) { 316 drawGlyphsToContext(shadowContext->platformContext()->cr(), scaledFont, syntheticBoldOffset, glyphs); 317 shadow.endShadowLayer(targetContext); 318 } 352 shadow.drawShadowLayer(State::getCTM(platformContext), State::getClipBounds(platformContext), fontExtentsRect, 353 [scaledFont, syntheticBoldOffset, &glyphs](GraphicsContext& shadowContext) 354 { 355 drawGlyphsToContext(shadowContext.platformContext()->cr(), scaledFont, syntheticBoldOffset, glyphs); 356 }, 357 [&platformContext, &shadowState, &targetContext](ImageBuffer& layerImage, const FloatPoint& layerOrigin, const FloatSize& layerSize, const FloatRect&) 358 { 359 drawShadowLayerBuffer(platformContext, layerImage, layerOrigin, layerSize, shadowState, targetContext); 360 }); 319 361 } 320 362 … … 563 605 , color(state.shadowColor) 564 606 , ignoreTransforms(state.shadowsIgnoreTransforms) 607 , globalAlpha(state.alpha) 608 , globalCompositeOperator(state.compositeOperator) 565 609 { 566 610 } … … 650 694 if (shadowState.isVisible()) { 651 695 ShadowBlur shadow({ shadowState.blur, shadowState.blur }, shadowState.offset, shadowState.color, shadowState.ignoreTransforms); 652 shadow.drawRectShadow(targetContext, FloatRoundedRect(rect)); 696 shadow.drawRectShadow(State::getCTM(platformContext), State::getClipBounds(platformContext), FloatRoundedRect(rect), 697 [&platformContext, &shadowState, &targetContext](ImageBuffer& layerImage, const FloatPoint& layerOrigin, const FloatSize& layerSize, const FloatRect& sourceRect) 698 { 699 fillShadowBuffer(platformContext, layerImage, layerOrigin, layerSize, sourceRect, shadowState, targetContext); 700 }); 653 701 } 654 702 … … 669 717 if (shadowState.isVisible()) { 670 718 ShadowBlur shadow({ shadowState.blur, shadowState.blur }, shadowState.offset, shadowState.color, shadowState.ignoreTransforms); 671 shadow.drawRectShadow(targetContext, rect); 719 shadow.drawRectShadow(State::getCTM(platformContext), State::getClipBounds(platformContext), rect, 720 [&platformContext, &shadowState, &targetContext](ImageBuffer& layerImage, const FloatPoint& layerOrigin, const FloatSize& layerSize, const FloatRect& sourceRect) 721 { 722 fillShadowBuffer(platformContext, layerImage, layerOrigin, layerSize, sourceRect, shadowState, targetContext); 723 }); 672 724 } 673 725 … … 690 742 if (shadowState.isRequired(platformContext)) { 691 743 ShadowBlur shadow({ shadowState.blur, shadowState.blur }, shadowState.offset, shadowState.color, shadowState.ignoreTransforms); 692 shadow.drawInsetShadow(targetContext, rect, roundedHoleRect); 744 shadow.drawInsetShadow(State::getCTM(platformContext), State::getClipBounds(platformContext), rect, roundedHoleRect, 745 [&platformContext, &shadowState, &targetContext](ImageBuffer& layerImage, const FloatPoint& layerOrigin, const FloatSize& layerSize, const FloatRect& sourceRect) 746 { 747 fillShadowBuffer(platformContext, layerImage, layerOrigin, layerSize, sourceRect, shadowState, targetContext); 748 }); 693 749 } 694 750 … … 814 870 } 815 871 816 void drawSurface(PlatformContextCairo& platformContext, cairo_surface_t* surface, const FloatRect& destRect, const FloatRect& originalSrcRect, InterpolationQuality imageInterpolationQuality, float globalAlpha, const ShadowState& shadowState, GraphicsContext& context)872 void drawSurface(PlatformContextCairo& platformContext, cairo_surface_t* surface, const FloatRect& destRect, const FloatRect& originalSrcRect, InterpolationQuality imageInterpolationQuality, float globalAlpha, const ShadowState& shadowState, GraphicsContext& targetContext) 817 873 { 818 874 // Avoid invalid cairo matrix with small values. … … 876 932 ShadowBlur shadow({ shadowState.blur, shadowState.blur }, shadowState.offset, shadowState.color, shadowState.ignoreTransforms); 877 933 if (shadow.type() != ShadowBlur::NoShadow) { 878 if (GraphicsContext* shadowContext = shadow.beginShadowLayer(context, destRect)) { 879 drawPatternToCairoContext(shadowContext->platformContext()->cr(), pattern.get(), destRect, 1); 880 shadow.endShadowLayer(context); 881 } 934 shadow.drawShadowLayer(State::getCTM(platformContext), State::getClipBounds(platformContext), destRect, 935 [&pattern, &destRect](GraphicsContext& shadowContext) 936 { 937 drawPatternToCairoContext(shadowContext.platformContext()->cr(), pattern.get(), destRect, 1); 938 }, 939 [&platformContext, &shadowState, &targetContext](ImageBuffer& layerImage, const FloatPoint& layerOrigin, const FloatSize& layerSize, const FloatRect&) 940 { 941 drawShadowLayerBuffer(platformContext, layerImage, layerOrigin, layerSize, shadowState, targetContext); 942 }); 882 943 } 883 944 -
trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.h
r227593 r228776 91 91 Color color; 92 92 93 WindRule fillRule ;93 WindRule fillRule { RULE_NONZERO }; 94 94 }; 95 95 … … 108 108 109 109 struct ShadowState { 110 ShadowState() = default; 110 111 WEBCORE_EXPORT explicit ShadowState(const GraphicsContextState&); 111 112 … … 117 118 Color color; 118 119 bool ignoreTransforms { false }; 120 121 float globalAlpha { 1.0 }; 122 CompositeOperator globalCompositeOperator { CompositeSourceOver }; 119 123 }; 120 124 -
trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h
r227292 r228776 31 31 #include "GraphicsContext.h" 32 32 #include "RefPtrCairo.h" 33 #include "ShadowBlur.h"34 33 35 34 namespace WebCore { -
trunk/Source/WebCore/rendering/RenderThemeGtk.cpp
r224371 r228776 29 29 #include "FileList.h" 30 30 #include "FileSystem.h" 31 #include "FloatRoundedRect.h" 31 32 #include "FontDescription.h" 32 33 #include "GRefPtrGtk.h"
Note: See TracChangeset
for help on using the changeset viewer.