Commit 4b82bf95 authored by mrobinson@webkit.org's avatar mrobinson@webkit.org

2011-04-06 Martin Robinson <mrobinson@igalia.com>

        Reviewed by Xan Lopez.

        [Cairo] Hide the details of image masking in PlatformContextCairo
        https://bugs.webkit.org/show_bug.cgi?id=57878

        No new tests. This is just a refactor.

        * platform/graphics/GraphicsContext.h:
        * platform/graphics/cairo/GraphicsContextCairo.cpp:
        (WebCore::GraphicsContext::savePlatformState): Call into PlatformContextCairo now to
        do the actual cairo_save. Remove information about image masking.
        (WebCore::GraphicsContext::restorePlatformState): Call into PlatformContextCairo now to
        do the actual cairo_restore. Remove information about image masking.
        * platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h:
        * platform/graphics/cairo/ImageBufferCairo.cpp:
        (WebCore::ImageBuffer::clip): Use PlatformContextCairo here now.
        * platform/graphics/cairo/PlatformContextCairo.cpp:
        (WebCore::PlatformContextCairo::restore): Added.
        (WebCore::PlatformContextCairo::save): Added.
        (WebCore::PlatformContextCairo::pushImageMask): Added.
        * platform/graphics/cairo/PlatformContextCairo.h:
        (WebCore::ImageMaskInformation::update): Moved from GraphicsContextPlatformPrivateCairo.h.
        (WebCore::ImageMaskInformation::isValid): Ditto.
        (WebCore::ImageMaskInformation::maskSurface): Ditto.
        (WebCore::ImageMaskInformation::maskRect): Ditto.

git-svn-id: svn://svn.chromium.org/blink/trunk@83044 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 969cac2f
2011-04-06 Martin Robinson <mrobinson@igalia.com>
Reviewed by Xan Lopez.
[Cairo] Hide the details of image masking in PlatformContextCairo
https://bugs.webkit.org/show_bug.cgi?id=57878
No new tests. This is just a refactor.
* platform/graphics/GraphicsContext.h:
* platform/graphics/cairo/GraphicsContextCairo.cpp:
(WebCore::GraphicsContext::savePlatformState): Call into PlatformContextCairo now to
do the actual cairo_save. Remove information about image masking.
(WebCore::GraphicsContext::restorePlatformState): Call into PlatformContextCairo now to
do the actual cairo_restore. Remove information about image masking.
* platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h:
* platform/graphics/cairo/ImageBufferCairo.cpp:
(WebCore::ImageBuffer::clip): Use PlatformContextCairo here now.
* platform/graphics/cairo/PlatformContextCairo.cpp:
(WebCore::PlatformContextCairo::restore): Added.
(WebCore::PlatformContextCairo::save): Added.
(WebCore::PlatformContextCairo::pushImageMask): Added.
* platform/graphics/cairo/PlatformContextCairo.h:
(WebCore::ImageMaskInformation::update): Moved from GraphicsContextPlatformPrivateCairo.h.
(WebCore::ImageMaskInformation::isValid): Ditto.
(WebCore::ImageMaskInformation::maskSurface): Ditto.
(WebCore::ImageMaskInformation::maskRect): Ditto.
2011-04-02 Diego Gonzalez <diegohcg@webkit.org>
Reviewed by Csaba Osztrogonác.
......@@ -492,7 +492,6 @@ namespace WebCore {
#if PLATFORM(CAIRO)
GraphicsContext(cairo_t*);
void pushImageMask(cairo_surface_t*, const FloatRect&);
#endif
#if PLATFORM(GTK)
......
......@@ -235,24 +235,13 @@ PlatformContextCairo* GraphicsContext::platformContext() const
void GraphicsContext::savePlatformState()
{
cairo_save(platformContext()->cr());
platformContext()->save();
m_data->save();
m_data->shadowStack.append(m_data->shadow);
m_data->maskImageStack.append(ImageMaskInformation());
}
void GraphicsContext::restorePlatformState()
{
cairo_t* cr = platformContext()->cr();
const ImageMaskInformation& maskInformation = m_data->maskImageStack.last();
if (maskInformation.isValid()) {
const FloatRect& maskRect = maskInformation.maskRect();
cairo_pop_group_to_source(cr);
cairo_mask_surface(cr, maskInformation.maskSurface(), maskRect.x(), maskRect.y());
}
m_data->maskImageStack.removeLast();
if (m_data->shadowStack.isEmpty())
m_data->shadow = ContextShadow();
else {
......@@ -260,7 +249,7 @@ void GraphicsContext::restorePlatformState()
m_data->shadowStack.removeLast();
}
cairo_restore(cr);
platformContext()->restore();
m_data->restore();
}
......@@ -1191,33 +1180,6 @@ InterpolationQuality GraphicsContext::imageInterpolationQuality() const
return InterpolationDefault;
}
void GraphicsContext::pushImageMask(cairo_surface_t* surface, const FloatRect& rect)
{
// We must call savePlatformState at least once before we can use image masking,
// since we actually apply the mask in restorePlatformState.
ASSERT(!m_data->maskImageStack.isEmpty());
m_data->maskImageStack.last().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
// operation) during restorePlatformState.
// We want to allow the clipped elements to composite with the surface as it
// is now, but they are isolated in another group. To make this work, we're
// going to blit the current surface contents onto the new group once we push it.
cairo_t* cr = platformContext()->cr();
cairo_surface_t* currentTarget = cairo_get_target(cr);
cairo_surface_flush(currentTarget);
// Pushing a new group ensures that only things painted after this point are clipped.
cairo_push_group(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_set_source_surface(cr, currentTarget, 0, 0);
cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
cairo_fill(cr);
}
} // namespace WebCore
#endif // PLATFORM(CAIRO)
......@@ -47,25 +47,6 @@ typedef struct _GdkExposeEvent GdkExposeEvent;
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 it 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;
};
class GraphicsContextPlatformPrivate {
public:
GraphicsContextPlatformPrivate(PlatformContextCairo* newPlatformContext)
......@@ -121,7 +102,6 @@ public:
Vector<float> layers;
ContextShadow shadow;
Vector<ContextShadow> shadowStack;
Vector<ImageMaskInformation> maskImageStack;
#if PLATFORM(GTK)
GdkEventExpose* expose;
......
......@@ -117,7 +117,7 @@ PassRefPtr<Image> ImageBuffer::copyImage() const
void ImageBuffer::clip(GraphicsContext* context, const FloatRect& maskRect) const
{
context->pushImageMask(m_data.m_surface, maskRect);
context->platformContext()->pushImageMask(m_data.m_surface, maskRect);
}
void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect,
......
......@@ -35,4 +35,51 @@ PlatformContextCairo::PlatformContextCairo(cairo_t* cr)
{
}
void PlatformContextCairo::restore()
{
const ImageMaskInformation& maskInformation = m_maskImageStack.last();
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();
cairo_restore(m_cr.get());
}
void PlatformContextCairo::save()
{
m_maskImageStack.append(ImageMaskInformation());
cairo_save(m_cr.get());
}
void PlatformContextCairo::pushImageMask(cairo_surface_t* surface, const FloatRect& rect)
{
// We must call savePlatformState at least once before we can use image masking,
// since we actually apply the mask in restorePlatformState.
ASSERT(!m_data->maskImageStack.isEmpty());
m_maskImageStack.last().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
// operation) during restorePlatformState.
// We want to allow the clipped elements to composite with the surface as it
// is now, but they are isolated in another group. To make this work, we're
// going to blit the current surface contents onto the new group once we push it.
cairo_surface_t* currentTarget = cairo_get_target(m_cr.get());
cairo_surface_flush(currentTarget);
// Pushing a new group ensures that only things painted after this point are clipped.
cairo_push_group(m_cr.get());
cairo_set_operator(m_cr.get(), CAIRO_OPERATOR_SOURCE);
cairo_set_source_surface(m_cr.get(), currentTarget, 0, 0);
cairo_rectangle(m_cr.get(), rect.x(), rect.y(), rect.width(), rect.height());
cairo_fill(m_cr.get());
}
} // namespace WebCore
......@@ -31,6 +31,25 @@
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
......@@ -40,11 +59,17 @@ class PlatformContextCairo {
WTF_MAKE_NONCOPYABLE(PlatformContextCairo);
public:
PlatformContextCairo(cairo_t*);
cairo_t* cr() { return m_cr.get(); }
void setCr(cairo_t* cr) { m_cr = cr; }
void save();
void restore();
void pushImageMask(cairo_surface_t*, const FloatRect&);
private:
RefPtr<cairo_t> m_cr;
Vector<ImageMaskInformation> m_maskImageStack;
};
} // namespace WebCore
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment