Diff
Modified: trunk/Source/WebCore/ChangeLog (87335 => 87336)
--- trunk/Source/WebCore/ChangeLog 2011-05-25 23:41:07 UTC (rev 87335)
+++ trunk/Source/WebCore/ChangeLog 2011-05-25 23:54:02 UTC (rev 87336)
@@ -1,3 +1,49 @@
+2011-05-25 Martin Robinson <mrobin...@igalia.com>
+
+ Reviewed by Dirk Schulze.
+
+ [Cairo] Move the global alpha property from GraphicsContext to PlatformContextCairo
+ https://bugs.webkit.org/show_bug.cgi?id=60185
+
+ Remove Cairo #ifdefs from GraphicsContext.h by pushing the global alpha
+ state into PlatformContextCairo. Since Cairo is the only platform that needs
+ to store this, this is the proper place for it. Change the image mask stack into
+ a more generic state stack that can keep track of the multiple bits of platform
+ specific state and properly handle save/restore pairs.
+
+ No new tests. This is just a code refactor.
+
+ * platform/graphics/GraphicsContext.h: Remove Cairo #ifdefs.
+ (WebCore::GraphicsContextState::GraphicsContextState): Ditto.
+ * platform/graphics/cairo/ContextShadowCairo.cpp: Access global alpha from PlatformContextCairo now.
+ (WebCore::ContextShadow::drawRectShadow):
+ * platform/graphics/cairo/FontCairo.cpp: Ditto.
+ (WebCore::Font::drawGlyphs):
+ * platform/graphics/cairo/GraphicsContextCairo.cpp:
+ (WebCore::setPlatformFill): Ditto.
+ (WebCore::setPlatformStroke): Ditto.
+ (WebCore::GraphicsContext::setAlpha): Ditto.
+ * platform/graphics/cairo/PlatformContextCairo.cpp: Moved ImageMaskInformation class from the
+ header file, since it can be private now. Abstract the image mask state and the global alpha
+ in a generic State class.
+ (WebCore::ImageMaskInformation::update):
+ (WebCore::ImageMaskInformation::isValid):
+ (WebCore::ImageMaskInformation::maskSurface):
+ (WebCore::ImageMaskInformation::maskRect):
+ (WebCore::PlatformContextCairo::State::State): Added.
+ (WebCore::PlatformContextCairo::PlatformContextCairo): Intialize the state
+ class when this class is constructed.
+ (WebCore::PlatformContextCairo::restore): Now pop the last state off the state stack.
+ (WebCore::PlatformContextCairo::~PlatformContextCairo): Added this so that we can forward
+ declare the State class in the header.
+ (WebCore::PlatformContextCairo::save): Push a new state onto the stack.
+ (WebCore::PlatformContextCairo::pushImageMask): Operate on the state stack now.
+ (WebCore::PlatformContextCairo::globalAlpha): Added.
+ (WebCore::PlatformContextCairo::setGlobalAlpha): Added.
+ (WebCore::PlatformContextCairo::drawSurfaceToContext: Call globalAlpha().
+ * platform/graphics/cairo/PlatformContextCairo.h: Changed the image mask stack
+ into a more generic state stack, much like PlatformContextChromium.
+
2011-05-25 Mark Rowe <mr...@apple.com>
Reviewed by Sam Weinig.
Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.h (87335 => 87336)
--- trunk/Source/WebCore/platform/graphics/GraphicsContext.h 2011-05-25 23:41:07 UTC (rev 87335)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.h 2011-05-25 23:54:02 UTC (rev 87336)
@@ -154,9 +154,6 @@
GraphicsContextState()
: strokeThickness(0)
, shadowBlur(0)
-#if USE(CAIRO)
- , globalAlpha(1)
-#endif
, textDrawingMode(TextModeFill)
, strokeColor(Color::black)
, fillColor(Color::black)
@@ -189,9 +186,6 @@
float strokeThickness;
float shadowBlur;
-#if USE(CAIRO)
- float globalAlpha;
-#endif
TextDrawingModeFlags textDrawingMode;
Color strokeColor;
@@ -390,9 +384,6 @@
void setMiterLimit(float);
void setAlpha(float);
-#if USE(CAIRO)
- float getAlpha();
-#endif
void setCompositeOperation(CompositeOperator);
CompositeOperator compositeOperation() const;
Modified: trunk/Source/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp (87335 => 87336)
--- trunk/Source/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp 2011-05-25 23:41:07 UTC (rev 87335)
+++ trunk/Source/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp 2011-05-25 23:54:02 UTC (rev 87336)
@@ -199,12 +199,13 @@
max(bottomLeftRadius.height(), bottomRightRadius.height());
cairo_t* cr = context->platformContext()->cr();
+ float globalAlpha = context->platformContext()->globalAlpha();
// drawShadowedRect still does not work with rotations.
// https://bugs.webkit.org/show_bug.cgi?id=45042
if ((!context->getCTM().isIdentityOrTranslationOrFlipped()) || (internalShadowWidth > rect.width())
|| (internalShadowHeight > rect.height()) || (m_type != BlurShadow)) {
- drawRectShadowWithoutTiling(context, rect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius, context->getAlpha());
+ drawRectShadowWithoutTiling(context, rect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius, globalAlpha);
return;
}
@@ -229,7 +230,7 @@
calculateLayerBoundingRect(context, shadowRect, IntRect(x1, y1, x2 - x1, y2 - y1));
if ((shadowTemplateSize.width() * shadowTemplateSize.height() > m_sourceRect.width() * m_sourceRect.height())) {
- drawRectShadowWithoutTiling(context, rect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius, context->getAlpha());
+ drawRectShadowWithoutTiling(context, rect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius, globalAlpha);
return;
}
@@ -251,7 +252,7 @@
path.addRoundedRect(templateRect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
appendWebCorePathToCairoContext(m_layerContext, path);
- cairo_set_source_rgba(m_layerContext, 0, 0, 0, context->getAlpha());
+ cairo_set_source_rgba(m_layerContext, 0, 0, 0, globalAlpha);
cairo_fill(m_layerContext);
// Blur the image.
Modified: trunk/Source/WebCore/platform/graphics/cairo/FontCairo.cpp (87335 => 87336)
--- trunk/Source/WebCore/platform/graphics/cairo/FontCairo.cpp 2011-05-25 23:41:07 UTC (rev 87335)
+++ trunk/Source/WebCore/platform/graphics/cairo/FontCairo.cpp 2011-05-25 23:54:02 UTC (rev 87336)
@@ -113,29 +113,32 @@
cairo_t* cr = platformContext->cr();
cairo_save(cr);
+
+ float globalAlpha = platformContext->globalAlpha();
+
prepareContextForGlyphDrawing(cr, font, point);
if (context->textDrawingMode() & TextModeFill) {
if (context->fillGradient()) {
cairo_set_source(cr, context->fillGradient()->platformGradient());
- if (context->getAlpha() < 1.0f) {
+ if (globalAlpha < 1) {
cairo_push_group(cr);
- cairo_paint_with_alpha(cr, context->getAlpha());
+ cairo_paint_with_alpha(cr, globalAlpha);
cairo_pop_group_to_source(cr);
}
} else if (context->fillPattern()) {
AffineTransform affine;
cairo_pattern_t* pattern = context->fillPattern()->createPlatformPattern(affine);
cairo_set_source(cr, pattern);
- if (context->getAlpha() < 1.0f) {
+ if (globalAlpha < 1) {
cairo_push_group(cr);
- cairo_paint_with_alpha(cr, context->getAlpha());
+ cairo_paint_with_alpha(cr, globalAlpha);
cairo_pop_group_to_source(cr);
}
cairo_pattern_destroy(pattern);
} else {
float red, green, blue, alpha;
context->fillColor().getRGBA(red, green, blue, alpha);
- cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha());
+ cairo_set_source_rgba(cr, red, green, blue, alpha * globalAlpha);
}
drawGlyphsToContext(cr, font, glyphs, numGlyphs);
}
@@ -147,25 +150,25 @@
if (context->textDrawingMode() & TextModeStroke && context->strokeThickness() < 2 * offset) {
if (context->strokeGradient()) {
cairo_set_source(cr, context->strokeGradient()->platformGradient());
- if (context->getAlpha() < 1.0f) {
+ if (globalAlpha < 1) {
cairo_push_group(cr);
- cairo_paint_with_alpha(cr, context->getAlpha());
+ cairo_paint_with_alpha(cr, globalAlpha);
cairo_pop_group_to_source(cr);
}
} else if (context->strokePattern()) {
AffineTransform affine;
cairo_pattern_t* pattern = context->strokePattern()->createPlatformPattern(affine);
cairo_set_source(cr, pattern);
- if (context->getAlpha() < 1.0f) {
+ if (globalAlpha < 1) {
cairo_push_group(cr);
- cairo_paint_with_alpha(cr, context->getAlpha());
+ cairo_paint_with_alpha(cr, globalAlpha);
cairo_pop_group_to_source(cr);
}
cairo_pattern_destroy(pattern);
} else {
float red, green, blue, alpha;
context->strokeColor().getRGBA(red, green, blue, alpha);
- cairo_set_source_rgba(cr, red, green, blue, alpha * context->getAlpha());
+ cairo_set_source_rgba(cr, red, green, blue, alpha * globalAlpha);
}
cairo_glyph_path(cr, glyphs, numGlyphs);
cairo_set_line_width(cr, context->strokeThickness());
Modified: trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp (87335 => 87336)
--- trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp 2011-05-25 23:41:07 UTC (rev 87335)
+++ trunk/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp 2011-05-25 23:54:02 UTC (rev 87336)
@@ -85,7 +85,7 @@
else
setSourceRGBAFromColor(cr, context->fillColor());
cairo_clip_preserve(cr);
- cairo_paint_with_alpha(cr, state.globalAlpha);
+ cairo_paint_with_alpha(cr, context->platformContext()->globalAlpha());
cairo_restore(cr);
if (pattern)
cairo_pattern_destroy(pattern);
@@ -93,6 +93,7 @@
static inline void setPlatformStroke(GraphicsContext* context, cairo_t* cr)
{
+ float globalAlpha = context->platformContext()->globalAlpha();
cairo_pattern_t* pattern = 0;
cairo_save(cr);
@@ -104,12 +105,12 @@
} else if (state.strokeGradient)
cairo_set_source(cr, state.strokeGradient->platformGradient());
else {
- Color strokeColor = colorWithOverrideAlpha(context->strokeColor().rgb(), context->strokeColor().alpha() / 255.f * state.globalAlpha);
+ Color strokeColor = colorWithOverrideAlpha(context->strokeColor().rgb(), context->strokeColor().alpha() / 255.f * globalAlpha);
setSourceRGBAFromColor(cr, strokeColor);
}
- if (state.globalAlpha < 1.0f && (state.strokePattern || state.strokeGradient)) {
+ if (globalAlpha < 1.0f && (state.strokePattern || state.strokeGradient)) {
cairo_push_group(cr);
- cairo_paint_with_alpha(cr, state.globalAlpha);
+ cairo_paint_with_alpha(cr, globalAlpha);
cairo_pop_group_to_source(cr);
}
cairo_stroke_preserve(cr);
@@ -1010,14 +1011,9 @@
void GraphicsContext::setAlpha(float alpha)
{
- m_state.globalAlpha = alpha;
+ platformContext()->setGlobalAlpha(alpha);
}
-float GraphicsContext::getAlpha()
-{
- return m_state.globalAlpha;
-}
-
void GraphicsContext::setPlatformCompositeOperation(CompositeOperator op)
{
if (paintingDisabled())
Modified: trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp (87335 => 87336)
--- trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp 2011-05-25 23:41:07 UTC (rev 87335)
+++ trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp 2011-05-25 23:54:02 UTC (rev 87336)
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2011 Igalia S.L.
+ * Copyright (c) 2008, Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,27 +32,77 @@
namespace WebCore {
+// In Cairo image masking is immediate, so to emulate image clipping we must save masking
+// details as part of the context state and apply them during platform restore.
+class ImageMaskInformation {
+public:
+ void update(cairo_surface_t* maskSurface, const FloatRect& maskRect)
+ {
+ m_maskSurface = maskSurface;
+ m_maskRect = maskRect;
+ }
+
+ bool isValid() const { return m_maskSurface; }
+ cairo_surface_t* maskSurface() const { return m_maskSurface.get(); }
+ const FloatRect& maskRect() const { return m_maskRect; }
+
+private:
+ RefPtr<cairo_surface_t> m_maskSurface;
+ FloatRect m_maskRect;
+};
+
+
+// Encapsulates the additional painting state information we store for each
+// pushed graphics state.
+class PlatformContextCairo::State {
+public:
+ State()
+ : m_globalAlpha(1)
+ {
+ }
+
+ State(const State& state)
+ : m_globalAlpha(state.m_globalAlpha)
+ {
+ // We do not copy m_imageMaskInformation because otherwise it would be applied
+ // more than once during subsequent calls to restore().
+ }
+
+ ImageMaskInformation m_imageMaskInformation;
+ float m_globalAlpha;
+};
+
PlatformContextCairo::PlatformContextCairo(cairo_t* cr)
: m_cr(cr)
{
+ m_stateStack.append(State());
+ m_state = &m_stateStack.last();
}
void PlatformContextCairo::restore()
{
- const ImageMaskInformation& maskInformation = m_maskImageStack.last();
+ const ImageMaskInformation& maskInformation = m_state->m_imageMaskInformation;
if (maskInformation.isValid()) {
const FloatRect& maskRect = maskInformation.maskRect();
cairo_pop_group_to_source(m_cr.get());
cairo_mask_surface(m_cr.get(), maskInformation.maskSurface(), maskRect.x(), maskRect.y());
}
- m_maskImageStack.removeLast();
+ m_stateStack.removeLast();
+ ASSERT(!m_stateStack.isEmpty());
+ m_state = &m_stateStack.last();
+
cairo_restore(m_cr.get());
}
+PlatformContextCairo::~PlatformContextCairo()
+{
+}
+
void PlatformContextCairo::save()
{
- m_maskImageStack.append(ImageMaskInformation());
+ m_stateStack.append(State(*m_state));
+ m_state = &m_stateStack.last();
cairo_save(m_cr.get());
}
@@ -60,8 +111,8 @@
{
// We must call savePlatformState at least once before we can use image masking,
// since we actually apply the mask in restorePlatformState.
- ASSERT(!m_maskImageStack.isEmpty());
- m_maskImageStack.last().update(surface, rect);
+ ASSERT(!m_stateStack.isEmpty());
+ m_state->m_imageMaskInformation.update(surface, rect);
// Cairo doesn't support the notion of an image clip, so we push a group here
// and then paint it to the surface with an image mask (which is an immediate
@@ -127,9 +178,18 @@
}
cairo_save(m_cr.get());
- drawPatternToCairoContext(m_cr.get(), pattern.get(), destRect, context->getAlpha());
+ drawPatternToCairoContext(m_cr.get(), pattern.get(), destRect, globalAlpha());
cairo_restore(m_cr.get());
}
+float PlatformContextCairo::globalAlpha() const
+{
+ return m_state->m_globalAlpha;
+}
+void PlatformContextCairo::setGlobalAlpha(float globalAlpha)
+{
+ m_state->m_globalAlpha = globalAlpha;
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h (87335 => 87336)
--- trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h 2011-05-25 23:41:07 UTC (rev 87335)
+++ trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h 2011-05-25 23:54:02 UTC (rev 87336)
@@ -32,25 +32,6 @@
namespace WebCore {
-// In Cairo image masking is immediate, so to emulate image clipping we must save masking
-// details as part of the context state and apply them during platform restore.
-class ImageMaskInformation {
-public:
- void update(cairo_surface_t* maskSurface, const FloatRect& maskRect)
- {
- m_maskSurface = maskSurface;
- m_maskRect = maskRect;
- }
-
- bool isValid() const { return m_maskSurface; }
- cairo_surface_t* maskSurface() const { return m_maskSurface.get(); }
- const FloatRect& maskRect() const { return m_maskRect; }
-
-private:
- RefPtr<cairo_surface_t> m_maskSurface;
- FloatRect m_maskRect;
-};
-
// 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
@@ -60,12 +41,16 @@
WTF_MAKE_NONCOPYABLE(PlatformContextCairo);
public:
PlatformContextCairo(cairo_t*);
+ ~PlatformContextCairo();
cairo_t* cr() { return m_cr.get(); }
void setCr(cairo_t* cr) { m_cr = cr; }
void save();
void restore();
+ void setGlobalAlpha(float);
+ float globalAlpha() const;
+
void pushImageMask(cairo_surface_t*, const FloatRect&);
void drawSurfaceToContext(cairo_surface_t*, const FloatRect& destRect, const FloatRect& srcRect, GraphicsContext*);
@@ -74,7 +59,11 @@
private:
RefPtr<cairo_t> m_cr;
- Vector<ImageMaskInformation> m_maskImageStack;
+
+ class State;
+ State* m_state;
+ WTF::Vector<State> m_stateStack;
+
InterpolationQuality m_imageInterpolationQuality;
};