OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) | 2 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) |
3 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved. | 3 * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 19 matching lines...) Expand all Loading... |
30 #include "platform/Length.h" | 30 #include "platform/Length.h" |
31 #include "platform/MIMETypeRegistry.h" | 31 #include "platform/MIMETypeRegistry.h" |
32 #include "platform/PlatformInstrumentation.h" | 32 #include "platform/PlatformInstrumentation.h" |
33 #include "platform/RuntimeEnabledFeatures.h" | 33 #include "platform/RuntimeEnabledFeatures.h" |
34 #include "platform/SharedBuffer.h" | 34 #include "platform/SharedBuffer.h" |
35 #include "platform/TraceEvent.h" | 35 #include "platform/TraceEvent.h" |
36 #include "platform/geometry/FloatPoint.h" | 36 #include "platform/geometry/FloatPoint.h" |
37 #include "platform/geometry/FloatRect.h" | 37 #include "platform/geometry/FloatRect.h" |
38 #include "platform/geometry/FloatSize.h" | 38 #include "platform/geometry/FloatSize.h" |
39 #include "platform/graphics/BitmapImage.h" | 39 #include "platform/graphics/BitmapImage.h" |
| 40 #include "platform/graphics/ColorSpaceFilter.h" |
| 41 #include "platform/graphics/ColorSpaceProfile.h" |
40 #include "platform/graphics/DeferredImageDecoder.h" | 42 #include "platform/graphics/DeferredImageDecoder.h" |
41 #include "platform/graphics/GraphicsContext.h" | 43 #include "platform/graphics/GraphicsContext.h" |
| 44 #include "platform/graphics/GraphicsScreen.h" |
42 #include "public/platform/Platform.h" | 45 #include "public/platform/Platform.h" |
43 #include "public/platform/WebData.h" | 46 #include "public/platform/WebData.h" |
44 #include "third_party/skia/include/core/SkCanvas.h" | 47 #include "third_party/skia/include/core/SkCanvas.h" |
45 #include "third_party/skia/include/core/SkImage.h" | 48 #include "third_party/skia/include/core/SkImage.h" |
46 #include "third_party/skia/include/core/SkPictureRecorder.h" | 49 #include "third_party/skia/include/core/SkPictureRecorder.h" |
47 #include "wtf/MainThread.h" | 50 #include "wtf/MainThread.h" |
48 #include "wtf/StdLibExtras.h" | 51 #include "wtf/StdLibExtras.h" |
49 | 52 |
50 #include <math.h> | 53 #include <math.h> |
51 | 54 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 ctxt->setImageInterpolationQuality(InterpolationLow); | 180 ctxt->setImageInterpolationQuality(InterpolationLow); |
178 drawPattern(ctxt, srcRect, tileScaleFactor, patternPhase, op, dstRect); | 181 drawPattern(ctxt, srcRect, tileScaleFactor, patternPhase, op, dstRect); |
179 ctxt->setImageInterpolationQuality(previousInterpolationQuality); | 182 ctxt->setImageInterpolationQuality(previousInterpolationQuality); |
180 } else { | 183 } else { |
181 drawPattern(ctxt, srcRect, tileScaleFactor, patternPhase, op, dstRect); | 184 drawPattern(ctxt, srcRect, tileScaleFactor, patternPhase, op, dstRect); |
182 } | 185 } |
183 | 186 |
184 startAnimation(); | 187 startAnimation(); |
185 } | 188 } |
186 | 189 |
187 namespace { | 190 static PassRefPtr<SkShader> createPatternShader(const SkImage* image, SkPaint* p
aint, const SkMatrix& shaderMatrix, const FloatSize& spacing) |
188 | |
189 PassRefPtr<SkShader> createPatternShader(const SkImage* image, const SkMatrix& s
haderMatrix, | |
190 const SkPaint& paint, const FloatSize& spacing) | |
191 { | 191 { |
192 if (spacing.isZero()) | 192 if (spacing.isZero()) |
193 return adoptRef(image->newShader(SkShader::kRepeat_TileMode, SkShader::k
Repeat_TileMode, &shaderMatrix)); | 193 return adoptRef(image->newShader(SkShader::kRepeat_TileMode, SkShader::k
Repeat_TileMode, &shaderMatrix)); |
194 | 194 |
195 // Arbitrary tiling is currently only supported for SkPictureShader - so we
use it instead | 195 // Arbitrary tiling is currently only supported for SkPictureShader so use i
t, instead |
196 // of a plain bitmap shader to implement spacing. | 196 // of a plain bitmap shader, to implement spacing (CSS background-repeat: sp
ace). |
197 const SkRect tileRect = SkRect::MakeWH( | 197 SkRect tileRect = SkRect::MakeWH(image->width() + spacing.width(), image->he
ight() + spacing.height()); |
198 image->width() + spacing.width(), | |
199 image->height() + spacing.height()); | |
200 | 198 |
201 SkPictureRecorder recorder; | 199 SkPictureRecorder recorder; |
202 SkCanvas* canvas = recorder.beginRecording(tileRect); | 200 SkCanvas* canvas = recorder.beginRecording(tileRect); |
203 canvas->drawImage(image, 0, 0, &paint); | 201 canvas->drawImage(image, 0, 0, paint); |
204 RefPtr<const SkPicture> picture = adoptRef(recorder.endRecordingAsPicture())
; | 202 RefPtr<const SkPicture> picture = adoptRef(recorder.endRecordingAsPicture())
; |
205 | 203 |
206 return adoptRef(SkShader::CreatePictureShader( | 204 // Remove any color filter from callers paint: it is applied when drawing th
e SkPicture |
207 picture.get(), SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &
shaderMatrix, nullptr)); | 205 // shader so clearing it here prevents caller from applying the filter twice
. |
| 206 if (paint->getColorFilter()) |
| 207 paint->setColorFilter(nullptr); |
| 208 |
| 209 return adoptRef(SkShader::CreatePictureShader(picture.get(), SkShader::kRepe
at_TileMode, SkShader::kRepeat_TileMode, &shaderMatrix, nullptr)); |
208 } | 210 } |
209 | 211 |
210 } // anonymous namespace | 212 inline PassRefPtr<ColorSpaceProfile> sourceColorProfile(Image* image) |
| 213 { |
| 214 return image->isBitmapImage() ? toBitmapImage(image)->colorProfile() : nullp
tr; |
| 215 } |
211 | 216 |
212 void Image::drawPattern(GraphicsContext* context, const FloatRect& floatSrcRect,
const FloatSize& scale, | 217 void Image::drawPattern(GraphicsContext* context, const FloatRect& floatSrcRect,
const FloatSize& scale, |
213 const FloatPoint& phase, SkXfermode::Mode compositeOp, const FloatRect& dest
Rect, const IntSize& repeatSpacing) | 218 const FloatPoint& phase, SkXfermode::Mode compositeOp, const FloatRect& dest
Rect, const IntSize& repeatSpacing) |
214 { | 219 { |
215 TRACE_EVENT0("skia", "Image::drawPattern"); | 220 TRACE_EVENT0("skia", "Image::drawPattern"); |
216 | 221 |
217 RefPtr<SkImage> image = imageForCurrentFrame(); | 222 RefPtr<SkImage> image = imageForCurrentFrame(); |
218 if (!image) | 223 if (!image) |
219 return; | 224 return; |
220 | 225 |
(...skipping 16 matching lines...) Expand all Loading... |
237 // set to the pattern's transform, which just includes scale. | 242 // set to the pattern's transform, which just includes scale. |
238 localMatrix.preScale(scale.width(), scale.height()); | 243 localMatrix.preScale(scale.width(), scale.height()); |
239 | 244 |
240 // Fetch this now as subsetting may swap the image. | 245 // Fetch this now as subsetting may swap the image. |
241 auto imageID = image->uniqueID(); | 246 auto imageID = image->uniqueID(); |
242 | 247 |
243 image = adoptRef(image->newSubset(enclosingIntRect(normSrcRect))); | 248 image = adoptRef(image->newSubset(enclosingIntRect(normSrcRect))); |
244 if (!image) | 249 if (!image) |
245 return; | 250 return; |
246 | 251 |
247 { | 252 RefPtr<SkColorFilter> colorTransform; |
248 SkPaint paint = context->fillPaint(); | 253 if (RefPtr<ColorSpaceProfile> source = sourceColorProfile(this)) { |
249 paint.setColor(SK_ColorBLACK); | 254 // Tagged images (those that have a color profile) are drawn color-corre
ct on supported platforms. |
250 paint.setXfermodeMode(compositeOp); | 255 RefPtr<ColorSpaceProfile> screen = screenColorProfile(currentScreenId())
; |
251 paint.setFilterQuality(context->computeFilterQuality(this, destRect, nor
mSrcRect)); | 256 if (!context->colorFilter()) // http://crbug.com/542498 |
252 paint.setAntiAlias(context->shouldAntialias()); | 257 colorTransform = createColorSpaceFilter(source.get(), screen.get()); |
253 RefPtr<SkShader> shader = createPatternShader(image.get(), localMatrix,
paint, | 258 RELEASE_ASSERT(currentScreenId()); |
254 FloatSize(repeatSpacing.width() / scale.width(), repeatSpacing.heigh
t() / scale.height())); | 259 } else { |
255 paint.setShader(shader.get()); | 260 // For sRGB assumed images: easy, just interpolate the sRGB color profil
e here as the src profile? |
256 context->drawRect(destRect, paint); | 261 // FIXME: untagged images should be drawn from sRGB color space, per CSS
2.1 onwards, a change that |
| 262 // would also require that all CSS content, including <canvas>, be drawn
from sRGB space to match, |
| 263 // and the same for plugins (Flash, NaCl) which don't define their color
space at all, <video> and |
| 264 // OOPIF, and so on ... |
257 } | 265 } |
258 | 266 |
| 267 SkPaint paint = context->fillPaint(); |
| 268 paint.setColor(SK_ColorBLACK); |
| 269 paint.setXfermodeMode(compositeOp); |
| 270 paint.setFilterQuality(context->computeFilterQuality(this, destRect, normSrc
Rect)); |
| 271 paint.setAntiAlias(context->shouldAntialias()); |
| 272 |
| 273 // BoxPainter background paint can set a luminance color filter on the conte
xt. Add it to the paint if |
| 274 // present: see layout test css3/masking/mask-luminance-png.html and http://
crbug.com/542498 |
| 275 if (context->colorFilter()) { |
| 276 fprintf(stderr, "Image::drawPattern color filter\n"); |
| 277 paint.setColorFilter(context->colorFilter()); |
| 278 fflush(stderr); |
| 279 } else if (colorTransform.get()) { |
| 280 fprintf(stderr, "Image::drawPattern color transform key [%s]\n", colorSp
aceFilterKey(colorTransform.get()).latin1().data()); |
| 281 paint.setColorFilter(colorTransform.get()); |
| 282 fflush(stderr); |
| 283 } |
| 284 |
| 285 FloatSize spacing = FloatSize(repeatSpacing.width() / scale.width(), repeatS
pacing.height() / scale.height()); |
| 286 RefPtr<SkShader> shader = createPatternShader(image.get(), &paint, localMatr
ix, spacing); |
| 287 paint.setShader(shader.get()); |
| 288 |
| 289 context->drawRect(destRect, paint); |
| 290 |
259 if (currentFrameIsLazyDecoded()) | 291 if (currentFrameIsLazyDecoded()) |
260 PlatformInstrumentation::didDrawLazyPixelRef(imageID); | 292 PlatformInstrumentation::didDrawLazyPixelRef(imageID); |
261 } | 293 } |
262 | 294 |
263 void Image::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsic
Height, FloatSize& intrinsicRatio) | 295 void Image::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsic
Height, FloatSize& intrinsicRatio) |
264 { | 296 { |
265 intrinsicRatio = FloatSize(size()); | 297 intrinsicRatio = FloatSize(size()); |
266 intrinsicWidth = Length(intrinsicRatio.width(), Fixed); | 298 intrinsicWidth = Length(intrinsicRatio.width(), Fixed); |
267 intrinsicHeight = Length(intrinsicRatio.height(), Fixed); | 299 intrinsicHeight = Length(intrinsicRatio.height(), Fixed); |
268 } | 300 } |
269 | 301 |
270 PassRefPtr<Image> Image::imageForDefaultFrame() | 302 PassRefPtr<Image> Image::imageForDefaultFrame() |
271 { | 303 { |
272 RefPtr<Image> image(this); | 304 RefPtr<Image> image(this); |
273 | 305 |
274 return image.release(); | 306 return image.release(); |
275 } | 307 } |
276 | 308 |
277 bool Image::isTextureBacked() | 309 bool Image::isTextureBacked() |
278 { | 310 { |
279 return imageForCurrentFrame()->isTextureBacked(); | 311 return imageForCurrentFrame()->isTextureBacked(); |
280 } | 312 } |
281 | 313 |
282 } // namespace blink | 314 } // namespace blink |
OLD | NEW |