| 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 so clearing it here prevents caller from applying the filter twice
. |
| 205 if (paint->getColorFilter()) |
| 206 paint->setColorFilter(nullptr); |
| 207 |
| 208 return adoptRef(SkShader::CreatePictureShader(picture.get(), SkShader::kRepe
at_TileMode, SkShader::kRepeat_TileMode, &shaderMatrix, nullptr)); |
| 207 } | 209 } |
| 208 | 210 |
| 209 } // anonymous namespace | 211 inline PassRefPtr<ColorSpaceProfile> sourceColorProfile(Image* image) |
| 212 { |
| 213 return image->isBitmapImage() ? toBitmapImage(image)->colorProfile() : nullp
tr; |
| 214 } |
| 210 | 215 |
| 211 void Image::drawPattern(GraphicsContext& context, const FloatRect& floatSrcRect,
const FloatSize& scale, | 216 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) | 217 const FloatPoint& phase, SkXfermode::Mode compositeOp, const FloatRect& dest
Rect, const FloatSize& repeatSpacing) |
| 213 { | 218 { |
| 214 TRACE_EVENT0("skia", "Image::drawPattern"); | 219 TRACE_EVENT0("skia", "Image::drawPattern"); |
| 215 | 220 |
| 216 RefPtr<SkImage> image = imageForCurrentFrame(); | 221 RefPtr<SkImage> image = imageForCurrentFrame(); |
| 217 if (!image) | 222 if (!image) |
| 218 return; | 223 return; |
| 219 | 224 |
| 220 FloatRect normSrcRect = floatSrcRect; | 225 FloatRect normSrcRect = floatSrcRect; |
| 221 | 226 |
| 222 normSrcRect.intersect(FloatRect(0, 0, image->width(), image->height())); | 227 normSrcRect.intersect(FloatRect(0, 0, image->width(), image->height())); |
| 223 if (destRect.isEmpty() || normSrcRect.isEmpty()) | 228 if (destRect.isEmpty() || normSrcRect.isEmpty()) |
| 224 return; // nothing to draw | 229 return; // nothing to draw |
| 225 | 230 |
| 226 SkMatrix localMatrix; | 231 SkMatrix localMatrix; |
| 227 // We also need to translate it such that the origin of the pattern is the | 232 // 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 | 233 // 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 | 234 // 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. | 235 // a shifted image, it will shift it from there using the localMatrix. |
| 231 const float adjustedX = phase.x() + normSrcRect.x() * scale.width(); | 236 const float adjustedX = phase.x() + normSrcRect.x() * scale.width(); |
| 232 const float adjustedY = phase.y() + normSrcRect.y() * scale.height(); | 237 const float adjustedY = phase.y() + normSrcRect.y() * scale.height(); |
| 233 localMatrix.setTranslate(SkFloatToScalar(adjustedX), SkFloatToScalar(adjuste
dY)); | 238 localMatrix.setTranslate(SkFloatToScalar(adjustedX), SkFloatToScalar(adjuste
dY)); |
| 234 | 239 |
| 235 // Because no resizing occurred, the shader transform should be | 240 // Because no resizing occurred, the shader transform should be |
| 236 // set to the pattern's transform, which just includes scale. | 241 // set to the pattern's transform, which just includes scale. |
| 237 localMatrix.preScale(scale.width(), scale.height()); | 242 localMatrix.preScale(scale.width(), scale.height()); |
| 238 | 243 |
| 239 // Fetch this now as subsetting may swap the image. | 244 // Fetch the image ID now since subsetting may swap the image. |
| 240 auto imageID = image->uniqueID(); | 245 auto imageID = image->uniqueID(); |
| 241 | |
| 242 image = adoptRef(image->newSubset(enclosingIntRect(normSrcRect))); | 246 image = adoptRef(image->newSubset(enclosingIntRect(normSrcRect))); |
| 243 if (!image) | 247 if (!image) |
| 244 return; | 248 return; |
| 245 | 249 |
| 246 { | 250 RefPtr<SkColorFilter> colorTransform; |
| 247 SkPaint paint = context.fillPaint(); | 251 if (RefPtr<ColorSpaceProfile> source = sourceColorProfile(this)) { |
| 248 paint.setColor(SK_ColorBLACK); | 252 // Tagged images (those that have a color profile) are drawn color-corre
ct on supported platforms. |
| 249 paint.setXfermodeMode(compositeOp); | 253 RefPtr<ColorSpaceProfile> target = screenColorProfile(currentScreenId())
; |
| 250 paint.setFilterQuality(context.computeFilterQuality(this, destRect, norm
SrcRect)); | 254 if (!context.colorFilter()) // http://crbug.com/542498 |
| 251 paint.setAntiAlias(context.shouldAntialias()); | 255 colorTransform = createColorSpaceFilter(source.get(), target.get()); |
| 252 RefPtr<SkShader> shader = createPatternShader(image.get(), localMatrix,
paint, | 256 RELEASE_ASSERT(currentScreenId()); |
| 253 FloatSize(repeatSpacing.width() / scale.width(), repeatSpacing.heigh
t() / scale.height())); | |
| 254 paint.setShader(shader.get()); | |
| 255 context.drawRect(destRect, paint); | |
| 256 } | 257 } |
| 257 | 258 |
| 259 SkPaint paint = context.fillPaint(); |
| 260 paint.setColor(SK_ColorBLACK); |
| 261 paint.setXfermodeMode(compositeOp); |
| 262 paint.setFilterQuality(context.computeFilterQuality(this, destRect, normSrcR
ect)); |
| 263 paint.setAntiAlias(context.shouldAntialias()); |
| 264 |
| 265 // BoxPainter background paint can set a luminance color filter on the conte
xt. Add it to the paint if |
| 266 // present: see layout test css3/masking/mask-luminance-png.html and http://
crbug.com/542498 |
| 267 if (context.colorFilter()) { |
| 268 fprintf(stderr, "Image::drawPattern color filter\n"); |
| 269 paint.setColorFilter(context.colorFilter()); |
| 270 fflush(stderr); |
| 271 } else if (colorTransform.get()) { |
| 272 fprintf(stderr, "Image::drawPattern color transform key [%s]\n", colorSp
aceFilterKey(colorTransform.get()).latin1().data()); |
| 273 paint.setColorFilter(colorTransform.get()); |
| 274 fflush(stderr); |
| 275 } |
| 276 |
| 277 FloatSize spacing = FloatSize(repeatSpacing.width() / scale.width(), repeatS
pacing.height() / scale.height()); |
| 278 RefPtr<SkShader> shader = createPatternShader(image.get(), &paint, localMatr
ix, spacing); |
| 279 paint.setShader(shader.get()); |
| 280 |
| 281 context.drawRect(destRect, paint); |
| 282 |
| 258 if (currentFrameIsLazyDecoded()) | 283 if (currentFrameIsLazyDecoded()) |
| 259 PlatformInstrumentation::didDrawLazyPixelRef(imageID); | 284 PlatformInstrumentation::didDrawLazyPixelRef(imageID); |
| 260 } | 285 } |
| 261 | 286 |
| 262 void Image::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsic
Height, FloatSize& intrinsicRatio) | 287 void Image::computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsic
Height, FloatSize& intrinsicRatio) |
| 263 { | 288 { |
| 264 intrinsicRatio = FloatSize(size()); | 289 intrinsicRatio = FloatSize(size()); |
| 265 intrinsicWidth = Length(intrinsicRatio.width(), Fixed); | 290 intrinsicWidth = Length(intrinsicRatio.width(), Fixed); |
| 266 intrinsicHeight = Length(intrinsicRatio.height(), Fixed); | 291 intrinsicHeight = Length(intrinsicRatio.height(), Fixed); |
| 267 } | 292 } |
| 268 | 293 |
| 269 PassRefPtr<Image> Image::imageForDefaultFrame() | 294 PassRefPtr<Image> Image::imageForDefaultFrame() |
| 270 { | 295 { |
| 271 RefPtr<Image> image(this); | 296 RefPtr<Image> image(this); |
| 272 | 297 |
| 273 return image.release(); | 298 return image.release(); |
| 274 } | 299 } |
| 275 | 300 |
| 276 bool Image::isTextureBacked() | 301 bool Image::isTextureBacked() |
| 277 { | 302 { |
| 278 RefPtr<SkImage> image = imageForCurrentFrame(); | 303 RefPtr<SkImage> image = imageForCurrentFrame(); |
| 279 return image ? image->isTextureBacked() : false; | 304 return image ? image->isTextureBacked() : false; |
| 280 } | 305 } |
| 281 | 306 |
| 282 } // namespace blink | 307 } // namespace blink |
| OLD | NEW |