| Index: third_party/WebKit/Source/platform/graphics/Image.cpp
|
| diff --git a/third_party/WebKit/Source/platform/graphics/Image.cpp b/third_party/WebKit/Source/platform/graphics/Image.cpp
|
| index e06cf388b158dacdb761e8cd8c8d2473160bf96d..020d270c4bd7b6d94ee4d162228212bb8b19fd09 100644
|
| --- a/third_party/WebKit/Source/platform/graphics/Image.cpp
|
| +++ b/third_party/WebKit/Source/platform/graphics/Image.cpp
|
| @@ -37,8 +37,11 @@
|
| #include "platform/geometry/FloatRect.h"
|
| #include "platform/geometry/FloatSize.h"
|
| #include "platform/graphics/BitmapImage.h"
|
| +#include "platform/graphics/ColorSpaceFilter.h"
|
| +#include "platform/graphics/ColorSpaceProfile.h"
|
| #include "platform/graphics/DeferredImageDecoder.h"
|
| #include "platform/graphics/GraphicsContext.h"
|
| +#include "platform/graphics/GraphicsScreen.h"
|
| #include "public/platform/Platform.h"
|
| #include "public/platform/WebData.h"
|
| #include "third_party/skia/include/core/SkCanvas.h"
|
| @@ -184,30 +187,32 @@ void Image::drawTiled(GraphicsContext* ctxt, const FloatRect& dstRect, const Flo
|
| startAnimation();
|
| }
|
|
|
| -namespace {
|
| -
|
| -PassRefPtr<SkShader> createPatternShader(const SkImage* image, const SkMatrix& shaderMatrix,
|
| - const SkPaint& paint, const FloatSize& spacing)
|
| +static PassRefPtr<SkShader> createPatternShader(const SkImage* image, SkPaint* paint, const SkMatrix& shaderMatrix, const FloatSize& spacing)
|
| {
|
| if (spacing.isZero())
|
| return adoptRef(image->newShader(SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &shaderMatrix));
|
|
|
| - // Arbitrary tiling is currently only supported for SkPictureShader - so we use it instead
|
| - // of a plain bitmap shader to implement spacing.
|
| - const SkRect tileRect = SkRect::MakeWH(
|
| - image->width() + spacing.width(),
|
| - image->height() + spacing.height());
|
| + // Arbitrary tiling is currently only supported for SkPictureShader so use it, instead
|
| + // of a plain bitmap shader, to implement spacing (CSS background-repeat: space).
|
| + SkRect tileRect = SkRect::MakeWH(image->width() + spacing.width(), image->height() + spacing.height());
|
|
|
| SkPictureRecorder recorder;
|
| SkCanvas* canvas = recorder.beginRecording(tileRect);
|
| - canvas->drawImage(image, 0, 0, &paint);
|
| + canvas->drawImage(image, 0, 0, paint);
|
| RefPtr<const SkPicture> picture = adoptRef(recorder.endRecordingAsPicture());
|
|
|
| - return adoptRef(SkShader::CreatePictureShader(
|
| - picture.get(), SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &shaderMatrix, nullptr));
|
| + // Remove any color filter from callers paint: it is applied when drawing the SkPicture
|
| + // shader so clearing it here prevents caller from applying the filter twice.
|
| + if (paint->getColorFilter())
|
| + paint->setColorFilter(nullptr);
|
| +
|
| + return adoptRef(SkShader::CreatePictureShader(picture.get(), SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &shaderMatrix, nullptr));
|
| }
|
|
|
| -} // anonymous namespace
|
| +inline PassRefPtr<ColorSpaceProfile> sourceColorProfile(Image* image)
|
| +{
|
| + return image->isBitmapImage() ? toBitmapImage(image)->colorProfile() : nullptr;
|
| +}
|
|
|
| void Image::drawPattern(GraphicsContext* context, const FloatRect& floatSrcRect, const FloatSize& scale,
|
| const FloatPoint& phase, SkXfermode::Mode compositeOp, const FloatRect& destRect, const IntSize& repeatSpacing)
|
| @@ -244,18 +249,45 @@ void Image::drawPattern(GraphicsContext* context, const FloatRect& floatSrcRect,
|
| if (!image)
|
| return;
|
|
|
| - {
|
| - SkPaint paint = context->fillPaint();
|
| - paint.setColor(SK_ColorBLACK);
|
| - paint.setXfermodeMode(compositeOp);
|
| - paint.setFilterQuality(context->computeFilterQuality(this, destRect, normSrcRect));
|
| - paint.setAntiAlias(context->shouldAntialias());
|
| - RefPtr<SkShader> shader = createPatternShader(image.get(), localMatrix, paint,
|
| - FloatSize(repeatSpacing.width() / scale.width(), repeatSpacing.height() / scale.height()));
|
| - paint.setShader(shader.get());
|
| - context->drawRect(destRect, paint);
|
| + RefPtr<SkColorFilter> colorTransform;
|
| + if (RefPtr<ColorSpaceProfile> source = sourceColorProfile(this)) {
|
| + // Tagged images (those that have a color profile) are drawn color-correct on supported platforms.
|
| + RefPtr<ColorSpaceProfile> screen = screenColorProfile(currentScreenId());
|
| + if (!context->colorFilter()) // http://crbug.com/542498
|
| + colorTransform = createColorSpaceFilter(source.get(), screen.get());
|
| + RELEASE_ASSERT(currentScreenId());
|
| + } else {
|
| + // For sRGB assumed images: easy, just interpolate the sRGB color profile here as the src profile?
|
| + // FIXME: untagged images should be drawn from sRGB color space, per CSS2.1 onwards, a change that
|
| + // would also require that all CSS content, including <canvas>, be drawn from sRGB space to match,
|
| + // and the same for plugins (Flash, NaCl) which don't define their color space at all, <video> and
|
| + // OOPIF, and so on ...
|
| }
|
|
|
| + SkPaint paint = context->fillPaint();
|
| + paint.setColor(SK_ColorBLACK);
|
| + paint.setXfermodeMode(compositeOp);
|
| + paint.setFilterQuality(context->computeFilterQuality(this, destRect, normSrcRect));
|
| + paint.setAntiAlias(context->shouldAntialias());
|
| +
|
| + // BoxPainter background paint can set a luminance color filter on the context. Add it to the paint if
|
| + // present: see layout test css3/masking/mask-luminance-png.html and http://crbug.com/542498
|
| + if (context->colorFilter()) {
|
| + fprintf(stderr, "Image::drawPattern color filter\n");
|
| + paint.setColorFilter(context->colorFilter());
|
| + fflush(stderr);
|
| + } else if (colorTransform.get()) {
|
| + fprintf(stderr, "Image::drawPattern color transform key [%s]\n", colorSpaceFilterKey(colorTransform.get()).latin1().data());
|
| + paint.setColorFilter(colorTransform.get());
|
| + fflush(stderr);
|
| + }
|
| +
|
| + FloatSize spacing = FloatSize(repeatSpacing.width() / scale.width(), repeatSpacing.height() / scale.height());
|
| + RefPtr<SkShader> shader = createPatternShader(image.get(), &paint, localMatrix, spacing);
|
| + paint.setShader(shader.get());
|
| +
|
| + context->drawRect(destRect, paint);
|
| +
|
| if (currentFrameIsLazyDecoded())
|
| PlatformInstrumentation::didDrawLazyPixelRef(imageID);
|
| }
|
|
|