Title: [87336] trunk/Source/WebCore
Revision
87336
Author
mrobin...@webkit.org
Date
2011-05-25 16:54:02 -0700 (Wed, 25 May 2011)

Log Message

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.

Modified Paths

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;
 };
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to