Diff
Modified: trunk/Source/WebCore/ChangeLog (226510 => 226511)
--- trunk/Source/WebCore/ChangeLog 2018-01-08 14:43:50 UTC (rev 226510)
+++ trunk/Source/WebCore/ChangeLog 2018-01-08 15:00:38 UTC (rev 226511)
@@ -1,3 +1,71 @@
+2018-01-08 Zan Dobersek <[email protected]>
+
+ [Cairo] Use isolated fill and stroke source containers
+ https://bugs.webkit.org/show_bug.cgi?id=181386
+
+ Reviewed by Carlos Garcia Campos.
+
+ Generate fill and stroke source objects upon invocation of various Cairo
+ operations, initializing necessary data from the GraphicsContextState
+ object.
+
+ Cairo::FillSource and Cairo::StrokeSource structs are introduced, both
+ being default-constructible as well as providing a constructor that
+ accepts a GraphicsContextState object from which the appropriate
+ resources are created.
+
+ The FillSource and StrokeSource objects are then passed to
+ PlatformContextCairo's prepareForFilling() and prepareForStroking()
+ methods. Here the helper prepareCairoContextSource() function is now
+ invoked with cairo_pattern_t objects as pattern or gradient sources, or
+ the source color if neither cairo_pattern_t object is specified.
+
+ The FillSource and StrokeSource constructors mimic the previous behavior
+ of prepareCairoContextSource(). In case the source is a Pattern object,
+ a cairo_pattern_t object is created from that. In case of FillSource,
+ we also retrieve pattern size, transform and repetition information. In
+ case the source os a Gradient object, we create a 'base' cairo_pattern_t
+ object for a completely opaque alpha channel. Additionally, if the alpha
+ value on the state is not 1, we create an alpha-adjusted cairo_pattern_t
+ that is potentially used for any filling or stroking operation that has
+ to preserve transparency. If neither Pattern or Gradient objects are set
+ on the GraphicsContextState, we default to the current fill or stroke
+ color.
+
+ Overall, there's no change in behavior, this is simply a refactoring
+ that enables us to construct Cairo objects for filling and stroking
+ sources at the time of Cairo operation dispatch, instead of pulling down
+ GraphicsContextState deeper into the Cairo-specific code.
+
+ No new tests -- no change in functionality.
+
+ * platform/graphics/cairo/CairoOperations.cpp:
+ (WebCore::Cairo::drawPathShadow):
+ (WebCore::Cairo::fillCurrentCairoPath):
+ (WebCore::Cairo::FillSource::FillSource):
+ (WebCore::Cairo::StrokeSource::StrokeSource):
+ (WebCore::Cairo::fillRect):
+ (WebCore::Cairo::fillRectWithRoundedHole):
+ (WebCore::Cairo::fillPath):
+ (WebCore::Cairo::strokeRect):
+ (WebCore::Cairo::strokePath):
+ (WebCore::Cairo::drawGlyphs):
+ * platform/graphics/cairo/CairoOperations.h:
+ * platform/graphics/cairo/FontCairo.cpp:
+ (WebCore::FontCascade::drawGlyphs):
+ * platform/graphics/cairo/GraphicsContextCairo.cpp:
+ (WebCore::GraphicsContext::fillPath):
+ (WebCore::GraphicsContext::strokePath):
+ (WebCore::GraphicsContext::fillRect):
+ (WebCore::GraphicsContext::strokeRect):
+ (WebCore::GraphicsContext::fillRectWithRoundedHole):
+ * platform/graphics/cairo/PlatformContextCairo.cpp:
+ (WebCore::prepareCairoContextSource):
+ (WebCore::PlatformContextCairo::prepareForFilling):
+ (WebCore::PlatformContextCairo::prepareForStroking):
+ (WebCore::PlatformContextCairo::clipForPatternFilling):
+ * platform/graphics/cairo/PlatformContextCairo.h:
+
2018-01-08 Youenn Fablet <[email protected]>
navigator.onLine does not work inside service workers
Modified: trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp (226510 => 226511)
--- trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp 2018-01-08 14:43:50 UTC (rev 226510)
+++ trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp 2018-01-08 15:00:38 UTC (rev 226511)
@@ -66,7 +66,7 @@
FillAndStroke = Fill + Stroke
};
-static inline void drawPathShadow(PlatformContextCairo& platformContext, const GraphicsContextState& contextState, GraphicsContext& targetContext, PathDrawingStyle drawingStyle)
+static inline void drawPathShadow(PlatformContextCairo& platformContext, const FillSource& fillSource, const StrokeSource& strokeSource, GraphicsContext& targetContext, PathDrawingStyle drawingStyle)
{
ShadowBlur& shadow = platformContext.shadowBlur();
if (shadow.type() == ShadowBlur::NoShadow)
@@ -106,7 +106,7 @@
if (drawingStyle & Fill) {
cairo_save(cairoShadowContext);
cairo_append_path(cairoShadowContext, path.get());
- shadowContext->platformContext()->prepareForFilling(contextState, PlatformContextCairo::NoAdjustment);
+ shadowContext->platformContext()->prepareForFilling(fillSource, PlatformContextCairo::NoAdjustment);
cairo_fill(cairoShadowContext);
cairo_restore(cairoShadowContext);
}
@@ -113,7 +113,7 @@
if (drawingStyle & Stroke) {
cairo_append_path(cairoShadowContext, path.get());
- shadowContext->platformContext()->prepareForStroking(contextState, PlatformContextCairo::DoNotPreserveAlpha);
+ shadowContext->platformContext()->prepareForStroking(strokeSource, PlatformContextCairo::DoNotPreserveAlpha);
cairo_stroke(cairoShadowContext);
}
@@ -126,12 +126,12 @@
cairo_append_path(cairoContext, path.get());
}
-static inline void fillCurrentCairoPath(PlatformContextCairo& platformContext, const GraphicsContextState& contextState)
+static inline void fillCurrentCairoPath(PlatformContextCairo& platformContext, const FillSource& fillSource)
{
cairo_t* cr = platformContext.cr();
cairo_save(cr);
- platformContext.prepareForFilling(contextState, PlatformContextCairo::AdjustPatternForGlobalAlpha);
+ platformContext.prepareForFilling(fillSource, PlatformContextCairo::AdjustPatternForGlobalAlpha);
cairo_fill(cr);
cairo_restore(cr);
@@ -468,6 +468,38 @@
return true;
}
+FillSource::FillSource(const GraphicsContextState& state)
+{
+ if (state.fillPattern) {
+ pattern.object = adoptRef(state.fillPattern->createPlatformPattern(AffineTransform()));
+
+ auto& patternImage = state.fillPattern->tileImage();
+ pattern.size = FloatSize(patternImage.width(), patternImage.height());
+ pattern.transform = state.fillPattern->patternSpaceTransform();
+ pattern.repeatX = state.fillPattern->repeatX();
+ pattern.repeatY = state.fillPattern->repeatY();
+ } else if (state.fillGradient) {
+ gradient.base = adoptRef(state.fillGradient->createPlatformGradient(1));
+ if (state.alpha != 1)
+ gradient.alphaAdjusted = adoptRef(state.fillGradient->createPlatformGradient(state.alpha));
+ } else
+ color = state.fillColor;
+
+ fillRule = state.fillRule;
+}
+
+StrokeSource::StrokeSource(const GraphicsContextState& state)
+{
+ if (state.strokePattern)
+ pattern = adoptRef(state.strokePattern->createPlatformPattern(AffineTransform()));
+ else if (state.strokeGradient) {
+ gradient.base = adoptRef(state.strokeGradient->createPlatformGradient(1));
+ if (state.alpha != 1)
+ gradient.alphaAdjusted = adoptRef(state.strokeGradient->createPlatformGradient(state.alpha));
+ } else
+ color = state.strokeColor;
+}
+
void setLineCap(PlatformContextCairo& platformContext, LineCap lineCap)
{
cairo_line_cap_t cairoCap;
@@ -515,13 +547,13 @@
cairo_set_miter_limit(platformContext.cr(), miterLimit);
}
-void fillRect(PlatformContextCairo& platformContext, const FloatRect& rect, const GraphicsContextState& contextState, GraphicsContext& targetContext)
+void fillRect(PlatformContextCairo& platformContext, const FloatRect& rect, const FillSource& fillSource, GraphicsContext& targetContext)
{
cairo_t* cr = platformContext.cr();
cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
- drawPathShadow(platformContext, contextState, targetContext, Fill);
- fillCurrentCairoPath(platformContext, contextState);
+ drawPathShadow(platformContext, fillSource, { }, targetContext, Fill);
+ fillCurrentCairoPath(platformContext, fillSource);
}
void fillRect(PlatformContextCairo& platformContext, const FloatRect& rect, const Color& color, bool hasShadow, GraphicsContext& targetContext)
@@ -558,7 +590,7 @@
cairo_restore(cr);
}
-void fillRectWithRoundedHole(PlatformContextCairo& platformContext, const FloatRect& rect, const FloatRoundedRect& roundedHoleRect, const GraphicsContextState& contextState, const ShadowBlurUsage& shadowBlurUsage, GraphicsContext& targetContext)
+void fillRectWithRoundedHole(PlatformContextCairo& platformContext, const FloatRect& rect, const FloatRoundedRect& roundedHoleRect, const FillSource& fillSource, const ShadowBlurUsage& shadowBlurUsage, GraphicsContext& targetContext)
{
// FIXME: this should leverage the specified color.
@@ -576,20 +608,20 @@
cairo_save(cr);
setPathOnCairoContext(platformContext.cr(), path.platformPath()->context());
- fillCurrentCairoPath(platformContext, contextState);
+ fillCurrentCairoPath(platformContext, fillSource);
cairo_restore(cr);
}
-void fillPath(PlatformContextCairo& platformContext, const Path& path, const GraphicsContextState& contextState, GraphicsContext& targetContext)
+void fillPath(PlatformContextCairo& platformContext, const Path& path, const FillSource& fillSource, GraphicsContext& targetContext)
{
cairo_t* cr = platformContext.cr();
setPathOnCairoContext(cr, path.platformPath()->context());
- drawPathShadow(platformContext, contextState, targetContext, Fill);
- fillCurrentCairoPath(platformContext, contextState);
+ drawPathShadow(platformContext, fillSource, { }, targetContext, Fill);
+ fillCurrentCairoPath(platformContext, fillSource);
}
-void strokeRect(PlatformContextCairo& platformContext, const FloatRect& rect, float lineWidth, const GraphicsContextState& contextState, GraphicsContext& targetContext)
+void strokeRect(PlatformContextCairo& platformContext, const FloatRect& rect, float lineWidth, const StrokeSource& strokeSource, GraphicsContext& targetContext)
{
cairo_t* cr = platformContext.cr();
cairo_save(cr);
@@ -596,20 +628,20 @@
cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
cairo_set_line_width(cr, lineWidth);
- drawPathShadow(platformContext, contextState, targetContext, Stroke);
- platformContext.prepareForStroking(contextState);
+ drawPathShadow(platformContext, { }, strokeSource, targetContext, Stroke);
+ platformContext.prepareForStroking(strokeSource, PlatformContextCairo::PreserveAlpha);
cairo_stroke(cr);
cairo_restore(cr);
}
-void strokePath(PlatformContextCairo& platformContext, const Path& path, const GraphicsContextState& contextState, GraphicsContext& targetContext)
+void strokePath(PlatformContextCairo& platformContext, const Path& path, const StrokeSource& strokeSource, GraphicsContext& targetContext)
{
cairo_t* cr = platformContext.cr();
setPathOnCairoContext(cr, path.platformPath()->context());
- drawPathShadow(platformContext, contextState, targetContext, Stroke);
- platformContext.prepareForStroking(contextState);
+ drawPathShadow(platformContext, { }, strokeSource, targetContext, Stroke);
+ platformContext.prepareForStroking(strokeSource, PlatformContextCairo::PreserveAlpha);
cairo_stroke(cr);
}
@@ -624,7 +656,7 @@
cairo_restore(cr);
}
-void drawGlyphs(PlatformContextCairo& platformContext, const GraphicsContextState& state, const ShadowBlurUsage& shadowBlurUsage, const FloatPoint& point, cairo_scaled_font_t* scaledFont, double syntheticBoldOffset, const Vector<cairo_glyph_t>& glyphs, float xOffset, GraphicsContext& targetContext)
+void drawGlyphs(PlatformContextCairo& platformContext, const GraphicsContextState& state, const FillSource& fillSource, const StrokeSource& strokeSource, const ShadowBlurUsage& shadowBlurUsage, const FloatPoint& point, cairo_scaled_font_t* scaledFont, double syntheticBoldOffset, const Vector<cairo_glyph_t>& glyphs, float xOffset, GraphicsContext& targetContext)
{
drawGlyphsShadow(platformContext, state, shadowBlurUsage, point, scaledFont, syntheticBoldOffset, glyphs, targetContext);
@@ -632,7 +664,7 @@
cairo_save(cr);
if (state.textDrawingMode & TextModeFill) {
- platformContext.prepareForFilling(state, PlatformContextCairo::AdjustPatternForGlobalAlpha);
+ platformContext.prepareForFilling(fillSource, PlatformContextCairo::AdjustPatternForGlobalAlpha);
drawGlyphsToContext(cr, scaledFont, syntheticBoldOffset, glyphs);
}
@@ -641,7 +673,7 @@
// the text as even one single stroke would cover the full wdth of the text.
// See https://bugs.webkit.org/show_bug.cgi?id=33759.
if (state.textDrawingMode & TextModeStroke && state.strokeThickness < 2 * xOffset) {
- platformContext.prepareForStroking(state);
+ platformContext.prepareForStroking(strokeSource, PlatformContextCairo::PreserveAlpha);
cairo_set_line_width(cr, state.strokeThickness);
// This may disturb the CTM, but we are going to call cairo_restore soon after.
Modified: trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.h (226510 => 226511)
--- trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.h 2018-01-08 14:43:50 UTC (rev 226510)
+++ trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.h 2018-01-08 15:00:38 UTC (rev 226511)
@@ -77,6 +77,38 @@
} // namespace State
+struct FillSource {
+ FillSource() = default;
+ explicit FillSource(const GraphicsContextState&);
+
+ struct {
+ RefPtr<cairo_pattern_t> object;
+ FloatSize size;
+ AffineTransform transform;
+ bool repeatX { false };
+ bool repeatY { false };
+ } pattern;
+ struct {
+ RefPtr<cairo_pattern_t> base;
+ RefPtr<cairo_pattern_t> alphaAdjusted;
+ } gradient;
+ Color color;
+
+ WindRule fillRule;
+};
+
+struct StrokeSource {
+ StrokeSource() = default;
+ explicit StrokeSource(const GraphicsContextState&);
+
+ RefPtr<cairo_pattern_t> pattern;
+ struct {
+ RefPtr<cairo_pattern_t> base;
+ RefPtr<cairo_pattern_t> alphaAdjusted;
+ } gradient;
+ Color color;
+};
+
struct ShadowBlurUsage {
explicit ShadowBlurUsage(const GraphicsContextState&);
@@ -92,17 +124,17 @@
void setLineJoin(PlatformContextCairo&, LineJoin);
void setMiterLimit(PlatformContextCairo&, float);
-void fillRect(PlatformContextCairo&, const FloatRect&, const GraphicsContextState&, GraphicsContext&);
+void fillRect(PlatformContextCairo&, const FloatRect&, const FillSource&, GraphicsContext&);
void fillRect(PlatformContextCairo&, const FloatRect&, const Color&, bool, GraphicsContext&);
void fillRect(PlatformContextCairo&, const FloatRect&, cairo_pattern_t*);
void fillRoundedRect(PlatformContextCairo&, const FloatRoundedRect&, const Color&, bool, GraphicsContext&);
-void fillRectWithRoundedHole(PlatformContextCairo&, const FloatRect&, const FloatRoundedRect&, const GraphicsContextState&, const ShadowBlurUsage&, GraphicsContext&);
-void fillPath(PlatformContextCairo&, const Path&, const GraphicsContextState&, GraphicsContext&);
-void strokeRect(PlatformContextCairo&, const FloatRect&, float, const GraphicsContextState&, GraphicsContext&);
-void strokePath(PlatformContextCairo&, const Path&, const GraphicsContextState&, GraphicsContext&);
+void fillRectWithRoundedHole(PlatformContextCairo&, const FloatRect&, const FloatRoundedRect&, const FillSource&, const ShadowBlurUsage&, GraphicsContext&);
+void fillPath(PlatformContextCairo&, const Path&, const FillSource&, GraphicsContext&);
+void strokeRect(PlatformContextCairo&, const FloatRect&, float, const StrokeSource&, GraphicsContext&);
+void strokePath(PlatformContextCairo&, const Path&, const StrokeSource&, GraphicsContext&);
void clearRect(PlatformContextCairo&, const FloatRect&);
-void drawGlyphs(PlatformContextCairo&, const GraphicsContextState&, const ShadowBlurUsage&, const FloatPoint&, cairo_scaled_font_t*, double, const Vector<cairo_glyph_t>&, float, GraphicsContext&);
+void drawGlyphs(PlatformContextCairo&, const GraphicsContextState&, const FillSource&, const StrokeSource&, const ShadowBlurUsage&, const FloatPoint&, cairo_scaled_font_t*, double, const Vector<cairo_glyph_t>&, float, GraphicsContext&);
void drawNativeImage(PlatformContextCairo&, cairo_surface_t*, const FloatRect&, const FloatRect&, CompositeOperator, BlendMode, ImageOrientation, GraphicsContext&);
void drawPattern(PlatformContextCairo&, cairo_surface_t*, const IntSize&, const FloatRect&, const FloatRect&, const AffineTransform&, const FloatPoint&, CompositeOperator, BlendMode);
Modified: trunk/Source/WebCore/platform/graphics/cairo/FontCairo.cpp (226510 => 226511)
--- trunk/Source/WebCore/platform/graphics/cairo/FontCairo.cpp 2018-01-08 14:43:50 UTC (rev 226510)
+++ trunk/Source/WebCore/platform/graphics/cairo/FontCairo.cpp 2018-01-08 15:00:38 UTC (rev 226511)
@@ -72,7 +72,7 @@
ASSERT(context.hasPlatformContext());
auto& state = context.state();
- Cairo::drawGlyphs(*context.platformContext(), state, Cairo::ShadowBlurUsage(state), point, scaledFont, syntheticBoldOffset, glyphs, xOffset, context);
+ Cairo::drawGlyphs(*context.platformContext(), state, Cairo::FillSource(state), Cairo::StrokeSource(state), Cairo::ShadowBlurUsage(state), point, scaledFont, syntheticBoldOffset, glyphs, xOffset, context);
}
#if ENABLE(CSS3_TEXT_DECORATION_SKIP_INK)
Modified: trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp (226510 => 226511)
--- trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp 2018-01-08 14:43:50 UTC (rev 226510)
+++ trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp 2018-01-08 15:00:38 UTC (rev 226511)
@@ -188,7 +188,7 @@
}
ASSERT(hasPlatformContext());
- Cairo::fillPath(*platformContext(), path, state(), *this);
+ Cairo::fillPath(*platformContext(), path, Cairo::FillSource(state()), *this);
}
void GraphicsContext::strokePath(const Path& path)
@@ -202,7 +202,7 @@
}
ASSERT(hasPlatformContext());
- Cairo::strokePath(*platformContext(), path, state(), *this);
+ Cairo::strokePath(*platformContext(), path, Cairo::StrokeSource(state()), *this);
}
void GraphicsContext::fillRect(const FloatRect& rect)
@@ -216,7 +216,7 @@
}
ASSERT(hasPlatformContext());
- Cairo::fillRect(*platformContext(), rect, state(), *this);
+ Cairo::fillRect(*platformContext(), rect, Cairo::FillSource(state()), *this);
}
void GraphicsContext::fillRect(const FloatRect& rect, const Color& color)
@@ -523,7 +523,7 @@
}
ASSERT(hasPlatformContext());
- Cairo::strokeRect(*platformContext(), rect, lineWidth, state(), *this);
+ Cairo::strokeRect(*platformContext(), rect, lineWidth, Cairo::StrokeSource(state()), *this);
}
void GraphicsContext::setLineCap(LineCap lineCap)
@@ -679,7 +679,7 @@
ASSERT(hasPlatformContext());
auto& state = this->state();
- Cairo::fillRectWithRoundedHole(*platformContext(), rect, roundedHoleRect, state, Cairo::ShadowBlurUsage(state), *this);
+ Cairo::fillRectWithRoundedHole(*platformContext(), rect, roundedHoleRect, Cairo::FillSource(state), Cairo::ShadowBlurUsage(state), *this);
}
void GraphicsContext::drawPattern(Image& image, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform, const FloatPoint& phase, const FloatSize& spacing, CompositeOperator compositeOperator, BlendMode blendMode)
Modified: trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp (226510 => 226511)
--- trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp 2018-01-08 14:43:50 UTC (rev 226510)
+++ trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp 2018-01-08 15:00:38 UTC (rev 226511)
@@ -264,16 +264,17 @@
cairo_pop_group_to_source(cr);
}
-static void prepareCairoContextSource(cairo_t* cr, Pattern* pattern, Gradient* gradient, const Color& color, float globalAlpha)
+static void prepareCairoContextSource(cairo_t* cr, cairo_pattern_t* pattern, cairo_pattern_t* gradient, const Color& color, float globalAlpha)
{
if (pattern) {
- RefPtr<cairo_pattern_t> cairoPattern = adoptRef(pattern->createPlatformPattern(AffineTransform()));
- cairo_set_source(cr, cairoPattern.get());
+ // Pattern source
+ cairo_set_source(cr, pattern);
reduceSourceByAlpha(cr, globalAlpha);
} else if (gradient) {
- RefPtr<cairo_pattern_t> cairoPattern = adoptRef(gradient->createPlatformGradient(globalAlpha));
- cairo_set_source(cr, cairoPattern.get());
- } else { // Solid color source.
+ // Gradient source
+ cairo_set_source(cr, gradient);
+ } else {
+ // Solid color source
if (globalAlpha < 1)
setSourceRGBAFromColor(cr, colorWithOverrideAlpha(color.rgb(), color.alpha() / 255.f * globalAlpha));
else
@@ -281,32 +282,39 @@
}
}
-void PlatformContextCairo::prepareForFilling(const GraphicsContextState& state, PatternAdjustment patternAdjustment)
+void PlatformContextCairo::prepareForFilling(const Cairo::FillSource& fillSource, PatternAdjustment patternAdjustment)
{
- cairo_set_fill_rule(m_cr.get(), state.fillRule == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING);
- prepareCairoContextSource(m_cr.get(),
- state.fillPattern.get(),
- state.fillGradient.get(),
- state.fillColor,
- patternAdjustment == AdjustPatternForGlobalAlpha ? globalAlpha() : 1);
+ cairo_set_fill_rule(m_cr.get(), fillSource.fillRule == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING);
- if (state.fillPattern)
- clipForPatternFilling(state);
+ bool adjustForAlpha = patternAdjustment == AdjustPatternForGlobalAlpha;
+
+ auto* gradient = fillSource.gradient.base.get();
+ if (adjustForAlpha && fillSource.gradient.alphaAdjusted)
+ gradient = fillSource.gradient.alphaAdjusted.get();
+
+ prepareCairoContextSource(m_cr.get(), fillSource.pattern.object.get(), gradient,
+ fillSource.color, adjustForAlpha ? globalAlpha() : 1);
+
+ if (fillSource.pattern.object) {
+ clipForPatternFilling(fillSource.pattern.size, fillSource.pattern.transform,
+ fillSource.pattern.repeatX, fillSource.pattern.repeatY);
+ }
}
-void PlatformContextCairo::prepareForStroking(const GraphicsContextState& state, AlphaPreservation alphaPreservation)
+void PlatformContextCairo::prepareForStroking(const Cairo::StrokeSource& strokeSource, AlphaPreservation alphaPreservation)
{
- prepareCairoContextSource(m_cr.get(),
- state.strokePattern.get(),
- state.strokeGradient.get(),
- state.strokeColor,
- alphaPreservation == PreserveAlpha ? globalAlpha() : 1);
+ bool preserveAlpha = alphaPreservation == PreserveAlpha;
+
+ auto* gradient = strokeSource.gradient.base.get();
+ if (preserveAlpha && strokeSource.gradient.alphaAdjusted)
+ gradient = strokeSource.gradient.alphaAdjusted.get();
+
+ prepareCairoContextSource(m_cr.get(), strokeSource.pattern.get(), gradient,
+ strokeSource.color, preserveAlpha ? globalAlpha() : 1);
}
-void PlatformContextCairo::clipForPatternFilling(const GraphicsContextState& state)
+void PlatformContextCairo::clipForPatternFilling(const FloatSize& patternSize, const AffineTransform& patternTransform, bool repeatX, bool repeatY)
{
- ASSERT(state.fillPattern);
-
// Hold current cairo path in a variable for restoring it after configuring the pattern clip rectangle.
auto currentPath = cairo_copy_path(m_cr.get());
cairo_new_path(m_cr.get());
@@ -317,13 +325,8 @@
cairo_clip_extents(m_cr.get(), &x1, &y1, &x2, &y2);
FloatRect clipRect(x1, y1, x2 - x1, y2 - y1);
- auto& patternImage = state.fillPattern->tileImage();
- const AffineTransform& patternTransform = state.fillPattern->patternSpaceTransform();
- FloatRect patternRect = patternTransform.mapRect(FloatRect(0, 0, patternImage.width(), patternImage.height()));
+ FloatRect patternRect = patternTransform.mapRect(FloatRect(FloatPoint(), patternSize));
- bool repeatX = state.fillPattern->repeatX();
- bool repeatY = state.fillPattern->repeatY();
-
if (!repeatX) {
clipRect.setX(patternRect.x());
clipRect.setWidth(patternRect.width());
Modified: trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h (226510 => 226511)
--- trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h 2018-01-08 14:43:50 UTC (rev 226510)
+++ trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h 2018-01-08 15:00:38 UTC (rev 226511)
@@ -37,6 +37,11 @@
class GraphicsContextPlatformPrivate;
struct GraphicsContextState;
+namespace Cairo {
+struct FillSource;
+struct StrokeSource;
+}
+
// Much like PlatformContextSkia in the Skia port, this class holds information that
// would normally be private to GraphicsContext, except that we want to allow access
// to it in Font and Image code. This allows us to separate the concerns of Cairo-specific
@@ -69,13 +74,13 @@
InterpolationQuality imageInterpolationQuality() const;
enum PatternAdjustment { NoAdjustment, AdjustPatternForGlobalAlpha };
- void prepareForFilling(const GraphicsContextState&, PatternAdjustment);
+ void prepareForFilling(const Cairo::FillSource&, PatternAdjustment);
enum AlphaPreservation { DoNotPreserveAlpha, PreserveAlpha };
- void prepareForStroking(const GraphicsContextState&, AlphaPreservation = PreserveAlpha);
+ void prepareForStroking(const Cairo::StrokeSource&, AlphaPreservation);
private:
- void clipForPatternFilling(const GraphicsContextState&);
+ void clipForPatternFilling(const FloatSize&, const AffineTransform&, bool, bool);
RefPtr<cairo_t> m_cr;