static inline void drawPathShadow(GraphicsContext* context, PathDrawingStyle drawingStyle) { ShadowBlur& shadow = context->platformContext()->shadowBlur(); if (shadow.type() == ShadowBlur::NoShadow) return; // Calculate the extents of the rendered solid paths. cairo_t* cairoContext = context->platformContext()->cr(); OwnPtr<cairo_path_t> path = adoptPtr(cairo_copy_path(cairoContext)); FloatRect solidFigureExtents; double x0 = 0; double x1 = 0; double y0 = 0; double y1 = 0; if (drawingStyle & Stroke) { cairo_stroke_extents(cairoContext, &x0, &y0, &x1, &y1); solidFigureExtents = FloatRect(x0, y0, x1 - x0, y1 - y0); } if (drawingStyle & Fill) { cairo_fill_extents(cairoContext, &x0, &y0, &x1, &y1); FloatRect fillExtents(x0, y0, x1 - x0, y1 - y0); solidFigureExtents.unite(fillExtents); } GraphicsContext* shadowContext = shadow.beginShadowLayer(context, solidFigureExtents); if (!shadowContext) return; cairo_t* cairoShadowContext = shadowContext->platformContext()->cr(); // It's important to copy the context properties to the new shadow // context to preserve things such as the fill rule and stroke width. copyContextProperties(cairoContext, cairoShadowContext); if (drawingStyle & Fill) { cairo_save(cairoShadowContext); cairo_append_path(cairoShadowContext, path.get()); shadowContext->platformContext()->prepareForFilling(context->state(), PlatformContextCairo::NoAdjustment); cairo_fill(cairoShadowContext); cairo_restore(cairoShadowContext); } if (drawingStyle & Stroke) { cairo_append_path(cairoShadowContext, path.get()); shadowContext->platformContext()->prepareForStroking(context->state(), PlatformContextCairo::DoNotPreserveAlpha); cairo_stroke(cairoShadowContext); } // The original path may still be hanging around on the context and endShadowLayer // will take care of properly creating a path to draw the result shadow. We remove the path // temporarily and then restore it. // See: https://bugs.webkit.org/show_bug.cgi?id=108897 cairo_new_path(cairoContext); shadow.endShadowLayer(context); cairo_append_path(cairoContext, path.get()); }
static inline void drawPathShadow(GraphicsContext* context, PathDrawingStyle drawingStyle) { ShadowBlur& shadow = context->platformContext()->shadowBlur(); if (shadow.type() == ShadowBlur::NoShadow) return; // Calculate the extents of the rendered solid paths. cairo_t* cairoContext = context->platformContext()->cr(); OwnPtr<cairo_path_t> path = adoptPtr(cairo_copy_path(cairoContext)); FloatRect solidFigureExtents; double x0 = 0; double x1 = 0; double y0 = 0; double y1 = 0; if (drawingStyle & Stroke) { cairo_stroke_extents(cairoContext, &x0, &y0, &x1, &y1); solidFigureExtents = FloatRect(x0, y0, x1 - x0, y1 - y0); } if (drawingStyle & Fill) { cairo_fill_extents(cairoContext, &x0, &y0, &x1, &y1); FloatRect fillExtents(x0, y0, x1 - x0, y1 - y0); solidFigureExtents.unite(fillExtents); } GraphicsContext* shadowContext = shadow.beginShadowLayer(context, solidFigureExtents); if (!shadowContext) return; cairo_t* cairoShadowContext = shadowContext->platformContext()->cr(); // It's important to copy the context properties to the new shadow // context to preserve things such as the fill rule and stroke width. copyContextProperties(cairoContext, cairoShadowContext); if (drawingStyle & Fill) { cairo_save(cairoShadowContext); cairo_append_path(cairoShadowContext, path.get()); shadowContext->platformContext()->prepareForFilling(context->state(), PlatformContextCairo::NoAdjustment); cairo_clip(cairoShadowContext); cairo_paint(cairoShadowContext); cairo_restore(cairoShadowContext); } if (drawingStyle & Stroke) { cairo_append_path(cairoShadowContext, path.get()); shadowContext->platformContext()->prepareForStroking(context->state(), PlatformContextCairo::DoNotPreserveAlpha); cairo_stroke(cairoShadowContext); } shadow.endShadowLayer(context); // ShadowBlur::endShadowLayer destroys the current path on the Cairo context. We restore it here. cairo_new_path(cairoContext); cairo_append_path(cairoContext, path.get()); }