| 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 ed58bd10ca9fa0e793a0eccd991e95c36dc51f0f..4366c274d437693a352b5b974c5c6c1f0e85e2a3 100644
|
| --- a/third_party/WebKit/Source/platform/graphics/Image.cpp
|
| +++ b/third_party/WebKit/Source/platform/graphics/Image.cpp
|
| @@ -36,8 +36,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"
|
| @@ -183,30 +186,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 FloatSize& repeatSpacing)
|
| @@ -236,25 +241,45 @@ void Image::drawPattern(GraphicsContext& context, const FloatRect& floatSrcRect,
|
| // set to the pattern's transform, which just includes scale.
|
| localMatrix.preScale(scale.width(), scale.height());
|
|
|
| - // Fetch this now as subsetting may swap the image.
|
| + // Fetch the image ID now since subsetting may swap the image.
|
| auto imageID = image->uniqueID();
|
| -
|
| image = adoptRef(image->newSubset(enclosingIntRect(normSrcRect)));
|
| 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> target = screenColorProfile(currentScreenId());
|
| + if (!context.colorFilter()) // http://crbug.com/542498
|
| + colorTransform = createColorSpaceFilter(source.get(), target.get());
|
| + RELEASE_ASSERT(currentScreenId());
|
| }
|
|
|
| + 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);
|
| }
|
|
|