Index: third_party/WebKit/WebCore/platform/graphics/skia/PlatformContextSkia.cpp |
=================================================================== |
--- third_party/WebKit/WebCore/platform/graphics/skia/PlatformContextSkia.cpp (revision 8367) |
+++ third_party/WebKit/WebCore/platform/graphics/skia/PlatformContextSkia.cpp (working copy) |
@@ -31,6 +31,7 @@ |
#include "config.h" |
#include "GraphicsContext.h" |
+#include "ImageBuffer.h" |
#include "NativeImageSkia.h" |
#include "PlatformContextSkia.h" |
#include "SkiaUtils.h" |
@@ -86,6 +87,13 @@ |
// color to produce a new output color. |
SkColor applyAlpha(SkColor) const; |
+#if defined(__linux__) || PLATFORM(WIN_OS) |
+ // If non-empty, the current State is clipped to this image. |
+ SkBitmap m_imageBufferClip; |
+ // If m_imageBufferClip is non-empty, this is the region the image is clipped to. |
+ WebCore::FloatRect m_clip; |
+#endif |
+ |
private: |
// Not supported. |
void operator=(const State&); |
@@ -148,6 +156,9 @@ |
PlatformContextSkia::PlatformContextSkia(skia::PlatformCanvas* canvas) |
: m_canvas(canvas) |
, m_stateStack(sizeof(State)) |
+#if PLATFORM(WIN_OS) |
+ , m_drawingToImageBuffer(false) |
+#endif |
{ |
m_stateStack.append(State()); |
m_state = &m_stateStack.last(); |
@@ -171,6 +182,18 @@ |
m_canvas = canvas; |
} |
+#if PLATFORM(WIN_OS) |
+void PlatformContextSkia::setDrawingToImageBuffer(bool value) |
+{ |
+ m_drawingToImageBuffer = value; |
+} |
+ |
+bool PlatformContextSkia::isDrawingToImageBuffer() const |
+{ |
+ return m_drawingToImageBuffer; |
+} |
+#endif |
+ |
void PlatformContextSkia::save() |
{ |
m_stateStack.append(*m_state); |
@@ -180,8 +203,32 @@ |
canvas()->save(); |
} |
+#if defined(__linux__) || PLATFORM(WIN_OS) |
+void PlatformContextSkia::beginLayerClippedToImage(const WebCore::FloatRect& rect, |
+ const WebCore::ImageBuffer* imageBuffer) |
+{ |
+ // Skia doesn't support clipping to an image, so we create a layer. The next |
+ // time restore is invoked the layer and |imageBuffer| are combined to |
+ // create the resulting image. |
+ m_state->m_clip = rect; |
+ SkRect bounds = { SkFloatToScalar(rect.x()), SkFloatToScalar(rect.y()), |
+ SkFloatToScalar(rect.right()), SkFloatToScalar(rect.bottom()) }; |
+ |
+ canvas()->saveLayerAlpha(&bounds, 255, |
+ static_cast<SkCanvas::SaveFlags>(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag)); |
+ // Copy off the image as |imageBuffer| may be deleted before restore is invoked. |
+ m_state->m_imageBufferClip = *(imageBuffer->context()->platformContext()->bitmap()); |
+} |
+#endif |
void PlatformContextSkia::restore() |
{ |
+#if defined(__linux__) || PLATFORM(WIN_OS) |
+ if (!m_state->m_imageBufferClip.empty()) { |
+ applyClipFromImage(m_state->m_clip, m_state->m_imageBufferClip); |
+ canvas()->restore(); |
+ } |
+#endif |
+ |
m_stateStack.removeLast(); |
m_state = &m_stateStack.last(); |
@@ -434,3 +481,14 @@ |
{ |
return m_canvas->getTopPlatformDevice().IsVectorial(); |
} |
+ |
+#if defined(__linux__) || PLATFORM(WIN_OS) |
+void PlatformContextSkia::applyClipFromImage(const WebCore::FloatRect& rect, const SkBitmap& imageBuffer) |
+{ |
+ // NOTE: this assumes the image mask contains opaque black for the portions that are to be shown, as such we |
+ // only look at the alpha when compositing. I'm not 100% sure this is what WebKit expects for image clipping. |
+ SkPaint paint; |
+ paint.setPorterDuffXfermode(SkPorterDuff::kDstIn_Mode); |
+ m_canvas->drawBitmap(imageBuffer, SkFloatToScalar(rect.x()), SkFloatToScalar(rect.y()), &paint); |
+} |
+#endif |