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 18 matching lines...) Expand all Loading... |
29 #include "platform/Length.h" | 29 #include "platform/Length.h" |
30 #include "platform/MIMETypeRegistry.h" | 30 #include "platform/MIMETypeRegistry.h" |
31 #include "platform/PlatformInstrumentation.h" | 31 #include "platform/PlatformInstrumentation.h" |
32 #include "platform/RuntimeEnabledFeatures.h" | 32 #include "platform/RuntimeEnabledFeatures.h" |
33 #include "platform/SharedBuffer.h" | 33 #include "platform/SharedBuffer.h" |
34 #include "platform/TraceEvent.h" | 34 #include "platform/TraceEvent.h" |
35 #include "platform/geometry/FloatPoint.h" | 35 #include "platform/geometry/FloatPoint.h" |
36 #include "platform/geometry/FloatRect.h" | 36 #include "platform/geometry/FloatRect.h" |
37 #include "platform/geometry/FloatSize.h" | 37 #include "platform/geometry/FloatSize.h" |
38 #include "platform/graphics/BitmapImage.h" | 38 #include "platform/graphics/BitmapImage.h" |
| 39 #include "platform/graphics/ColorSpaceFilter.h" |
| 40 #include "platform/graphics/ColorSpaceProfile.h" |
39 #include "platform/graphics/DeferredImageDecoder.h" | 41 #include "platform/graphics/DeferredImageDecoder.h" |
40 #include "platform/graphics/GraphicsContext.h" | 42 #include "platform/graphics/GraphicsContext.h" |
| 43 #include "platform/graphics/GraphicsScreen.h" |
41 #include "public/platform/Platform.h" | 44 #include "public/platform/Platform.h" |
42 #include "public/platform/WebData.h" | 45 #include "public/platform/WebData.h" |
43 #include "third_party/skia/include/core/SkCanvas.h" | 46 #include "third_party/skia/include/core/SkCanvas.h" |
44 #include "third_party/skia/include/core/SkImage.h" | 47 #include "third_party/skia/include/core/SkImage.h" |
45 #include "third_party/skia/include/core/SkPictureRecorder.h" | 48 #include "third_party/skia/include/core/SkPictureRecorder.h" |
46 #include "wtf/MainThread.h" | 49 #include "wtf/MainThread.h" |
47 #include "wtf/StdLibExtras.h" | 50 #include "wtf/StdLibExtras.h" |
48 | 51 |
49 #include <math.h> | 52 #include <math.h> |
50 | 53 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 ctxt.setImageInterpolationQuality(InterpolationLow); | 179 ctxt.setImageInterpolationQuality(InterpolationLow); |
177 drawPattern(ctxt, srcRect, tileScaleFactor, patternPhase, op, dstRect); | 180 drawPattern(ctxt, srcRect, tileScaleFactor, patternPhase, op, dstRect); |
178 ctxt.setImageInterpolationQuality(previousInterpolationQuality); | 181 ctxt.setImageInterpolationQuality(previousInterpolationQuality); |
179 } else { | 182 } else { |
180 drawPattern(ctxt, srcRect, tileScaleFactor, patternPhase, op, dstRect); | 183 drawPattern(ctxt, srcRect, tileScaleFactor, patternPhase, op, dstRect); |
181 } | 184 } |
182 | 185 |
183 startAnimation(); | 186 startAnimation(); |
184 } | 187 } |
185 | 188 |
186 namespace { | 189 static PassRefPtr<SkShader> createPatternShader(const SkImage* image, SkPaint* p
aint, const SkMatrix& shaderMatrix, const FloatSize& spacing) |
187 | |
188 PassRefPtr<SkShader> createPatternShader(const SkImage* image, const SkMatrix& s
haderMatrix, | |
189 const SkPaint& paint, const FloatSize& spacing) | |
190 { | 190 { |
191 if (spacing.isZero()) | 191 if (spacing.isZero()) |
192 return adoptRef(image->newShader(SkShader::kRepeat_TileMode, SkShader::k
Repeat_TileMode, &shaderMatrix)); | 192 return adoptRef(image->newShader(SkShader::kRepeat_TileMode, SkShader::k
Repeat_TileMode, &shaderMatrix)); |
193 | 193 |
194 // Arbitrary tiling is currently only supported for SkPictureShader - so we
use it instead | 194 // Arbitrary tiling is currently only supported for SkPictureShader so use i
t, instead |
195 // of a plain bitmap shader to implement spacing. | 195 // of a plain bitmap shader, to implement spacing (CSS background-repeat: sp
ace). |
196 const SkRect tileRect = SkRect::MakeWH( | 196 SkRect tileRect = SkRect::MakeWH(image->width() + spacing.width(), image->he
ight() + spacing.height()); |
197 image->width() + spacing.width(), | |
198 image->height() + spacing.height()); | |
199 | 197 |
200 SkPictureRecorder recorder; | 198 SkPictureRecorder recorder; |
201 SkCanvas* canvas = recorder.beginRecording(tileRect); | 199 SkCanvas* canvas = recorder.beginRecording(tileRect); |
202 canvas->drawImage(image, 0, 0, &paint); | 200 canvas->drawImage(image, 0, 0, paint); |
203 RefPtr<const SkPicture> picture = adoptRef(recorder.endRecordingAsPicture())
; | 201 RefPtr<const SkPicture> picture = adoptRef(recorder.endRecordingAsPicture())
; |
204 | 202 |
205 return adoptRef(SkShader::CreatePictureShader( | 203 // Remove any color filter from callers paint: it is applied when drawing th
e SkPicture |
206 picture.get(), SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &
shaderMatrix, nullptr)); | 204 // shader: clearing it here prevents caller from applying the filter twice. |
| 205 paint->setColorFilter(nullptr); |
| 206 |
| 207 return adoptRef(SkShader::CreatePictureShader(picture.get(), SkShader::kRepe
at_TileMode, SkShader::kRepeat_TileMode, &shaderMatrix, nullptr)); |
207 } | 208 } |
208 | 209 |
209 } // anonymous namespace | |
210 | |
211 void Image::drawPattern(GraphicsContext& context, const FloatRect& floatSrcRect,
const FloatSize& scale, | 210 void Image::drawPattern(GraphicsContext& context, const FloatRect& floatSrcRect,
const FloatSize& scale, |
212 const FloatPoint& phase, SkXfermode::Mode compositeOp, const FloatRect& dest
Rect, const FloatSize& repeatSpacing) | 211 const FloatPoint& phase, SkXfermode::Mode compositeOp, const FloatRect& dest
Rect, const FloatSize& repeatSpacing) |
213 { | 212 { |
214 TRACE_EVENT0("skia", "Image::drawPattern"); | 213 TRACE_EVENT0("skia", "Image::drawPattern"); |
215 | 214 |
216 RefPtr<SkImage> image = imageForCurrentFrame(); | 215 RefPtr<SkImage> image = imageForCurrentFrame(); |
217 if (!image) | 216 if (!image) |
218 return; | 217 return; |
219 | 218 |
220 FloatRect normSrcRect = floatSrcRect; | 219 FloatRect normSrcRect = floatSrcRect; |
221 | |
222 normSrcRect.intersect(FloatRect(0, 0, image->width(), image->height())); | 220 normSrcRect.intersect(FloatRect(0, 0, image->width(), image->height())); |
223 if (destRect.isEmpty() || normSrcRect.isEmpty()) | 221 if (destRect.isEmpty() || normSrcRect.isEmpty()) |
224 return; // nothing to draw | 222 return; // nothing to draw |
225 | 223 |
226 SkMatrix localMatrix; | 224 SkMatrix localMatrix; |
227 // We also need to translate it such that the origin of the pattern is the | 225 // We also need to translate it such that the origin of the pattern is the |
228 // origin of the destination rect, which is what WebKit expects. Skia uses | 226 // origin of the destination rect, which is what WebKit expects. Skia uses |
229 // the coordinate system origin as the base for the pattern. If WebKit wants | 227 // the coordinate system origin as the base for the pattern. If WebKit wants |
230 // a shifted image, it will shift it from there using the localMatrix. | 228 // a shifted image, it will shift it from there using the localMatrix. |
231 const float adjustedX = phase.x() + normSrcRect.x() * scale.width(); | 229 const float adjustedX = phase.x() + normSrcRect.x() * scale.width(); |
232 const float adjustedY = phase.y() + normSrcRect.y() * scale.height(); | 230 const float adjustedY = phase.y() + normSrcRect.y() * scale.height(); |
233 localMatrix.setTranslate(SkFloatToScalar(adjustedX), SkFloatToScalar(adjuste
dY)); | 231 localMatrix.setTranslate(SkFloatToScalar(adjustedX), SkFloatToScalar(adjuste
dY)); |
234 | 232 |
235 // Because no resizing occurred, the shader transform should be | 233 // Because no resizing occurred, the shader transform should be |
236 // set to the pattern's transform, which just includes scale. | 234 // set to the pattern's transform, which just includes scale. |
237 localMatrix.preScale(scale.width(), scale.height()); | 235 localMatrix.preScale(scale.width(), scale.height()); |
238 | 236 |
239 // Fetch this now as subsetting may swap the image. | 237 // Fetch the image ID now since subsetting and/or the application of color |
| 238 // transforms may swap out the image. |
240 auto imageID = image->uniqueID(); | 239 auto imageID = image->uniqueID(); |
241 | 240 |
| 241 if (imageColorProfilesEnabled() && this->isBitmapImage()) |
| 242 image = toBitmapImage(this)->pictureForCurrentFrame(); |
| 243 |
242 image = adoptRef(image->newSubset(enclosingIntRect(normSrcRect))); | 244 image = adoptRef(image->newSubset(enclosingIntRect(normSrcRect))); |
243 if (!image) | 245 if (!image) |
244 return; | 246 return; |
245 | 247 |
246 { | 248 SkPaint paint = context.fillPaint(); |
247 SkPaint paint = context.fillPaint(); | 249 paint.setColor(SK_ColorBLACK); // FIXME: not color correct. |
248 paint.setColor(SK_ColorBLACK); | 250 paint.setXfermodeMode(compositeOp); |
249 paint.setXfermodeMode(compositeOp); | 251 paint.setFilterQuality(context.computeFilterQuality(this, destRect, normSrcR
ect)); |
250 paint.setFilterQuality(context.computeFilterQuality(this, destRect, norm
SrcRect)); | 252 paint.setAntiAlias(context.shouldAntialias()); |
251 paint.setAntiAlias(context.shouldAntialias()); | 253 |
252 RefPtr<SkShader> shader = createPatternShader(image.get(), localMatrix,
paint, | 254 FloatSize spacing = FloatSize(repeatSpacing.width() / scale.width(), repeatS
pacing.height() / scale.height()); |
253 FloatSize(repeatSpacing.width() / scale.width(), repeatSpacing.heigh
t() / scale.height())); | 255 RefPtr<SkShader> shader = createPatternShader(image.get(), &paint, localMatr
ix, spacing); |
254 paint.setShader(shader.get()); | 256 paint.setShader(shader.get()); |
255 context.drawRect(destRect, paint); | 257 |
256 } | 258 context.drawRect(destRect, paint); |
257 | 259 |
258 if (currentFrameIsLazyDecoded()) | 260 if (currentFrameIsLazyDecoded()) |
259 PlatformInstrumentation::didDrawLazyPixelRef(imageID); | 261 PlatformInstrumentation::didDrawLazyPixelRef(imageID); |
260 } | 262 } |
261 | 263 |
262 void Image::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsic
Height, FloatSize& intrinsicRatio) | 264 void Image::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsic
Height, FloatSize& intrinsicRatio) |
263 { | 265 { |
264 intrinsicRatio = FloatSize(size()); | 266 intrinsicRatio = FloatSize(size()); |
265 intrinsicWidth = Length(intrinsicRatio.width(), Fixed); | 267 intrinsicWidth = Length(intrinsicRatio.width(), Fixed); |
266 intrinsicHeight = Length(intrinsicRatio.height(), Fixed); | 268 intrinsicHeight = Length(intrinsicRatio.height(), Fixed); |
267 } | 269 } |
268 | 270 |
269 PassRefPtr<Image> Image::imageForDefaultFrame() | 271 PassRefPtr<Image> Image::imageForDefaultFrame() |
270 { | 272 { |
271 RefPtr<Image> image(this); | 273 RefPtr<Image> image(this); |
272 | 274 |
273 return image.release(); | 275 return image.release(); |
274 } | 276 } |
275 | 277 |
276 bool Image::isTextureBacked() | 278 bool Image::isTextureBacked() |
277 { | 279 { |
278 RefPtr<SkImage> image = imageForCurrentFrame(); | 280 RefPtr<SkImage> image = imageForCurrentFrame(); |
279 return image ? image->isTextureBacked() : false; | 281 return image ? image->isTextureBacked() : false; |
280 } | 282 } |
281 | 283 |
282 } // namespace blink | 284 } // namespace blink |
OLD | NEW |