| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/graphics/ImagePattern.h" | 5 #include "platform/graphics/ImagePattern.h" |
| 6 | 6 |
| 7 #include "platform/graphics/Image.h" | 7 #include "platform/graphics/Image.h" |
| 8 #include "platform/graphics/skia/SkiaUtils.h" | 8 #include "platform/graphics/skia/SkiaUtils.h" |
| 9 #include "skia/ext/cdl_shader.h" |
| 9 #include "third_party/skia/include/core/SkCanvas.h" | 10 #include "third_party/skia/include/core/SkCanvas.h" |
| 10 #include "third_party/skia/include/core/SkImage.h" | 11 #include "third_party/skia/include/core/SkImage.h" |
| 11 #include "third_party/skia/include/core/SkShader.h" | 12 #include "third_party/skia/include/core/SkShader.h" |
| 12 #include "third_party/skia/include/core/SkSurface.h" | 13 #include "third_party/skia/include/core/SkSurface.h" |
| 13 | 14 |
| 14 namespace blink { | 15 namespace blink { |
| 15 | 16 |
| 16 PassRefPtr<ImagePattern> ImagePattern::create(PassRefPtr<Image> image, | 17 PassRefPtr<ImagePattern> ImagePattern::create(PassRefPtr<Image> image, |
| 17 RepeatMode repeatMode) { | 18 RepeatMode repeatMode) { |
| 18 return adoptRef(new ImagePattern(std::move(image), repeatMode)); | 19 return adoptRef(new ImagePattern(std::move(image), repeatMode)); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 30 adjustExternalMemoryAllocated(info.getSafeSize(info.minRowBytes())); | 31 adjustExternalMemoryAllocated(info.getSafeSize(info.minRowBytes())); |
| 31 } | 32 } |
| 32 } | 33 } |
| 33 | 34 |
| 34 bool ImagePattern::isLocalMatrixChanged(const SkMatrix& localMatrix) const { | 35 bool ImagePattern::isLocalMatrixChanged(const SkMatrix& localMatrix) const { |
| 35 if (isRepeatXY()) | 36 if (isRepeatXY()) |
| 36 return Pattern::isLocalMatrixChanged(localMatrix); | 37 return Pattern::isLocalMatrixChanged(localMatrix); |
| 37 return localMatrix != m_previousLocalMatrix; | 38 return localMatrix != m_previousLocalMatrix; |
| 38 } | 39 } |
| 39 | 40 |
| 40 sk_sp<SkShader> ImagePattern::createShader(const SkMatrix& localMatrix) { | 41 sk_sp<CdlShader> ImagePattern::createShader(const SkMatrix& localMatrix) { |
| 41 if (!m_tileImage) | 42 if (!m_tileImage) |
| 42 return SkShader::MakeColorShader(SK_ColorTRANSPARENT); | 43 return WrapSkShader(SkShader::MakeColorShader(SK_ColorTRANSPARENT)); |
| 43 | 44 |
| 44 if (isRepeatXY()) { | 45 if (isRepeatXY()) { |
| 45 // Fast path: for repeatXY we just return a shader from the original image. | 46 // Fast path: for repeatXY we just return a shader from the original image. |
| 46 return m_tileImage->makeShader(SkShader::kRepeat_TileMode, | 47 return MakeCdlImageShader(m_tileImage, SkShader::kRepeat_TileMode, |
| 47 SkShader::kRepeat_TileMode, &localMatrix); | 48 SkShader::kRepeat_TileMode, &localMatrix); |
| 48 } | 49 } |
| 49 | 50 |
| 50 // Skia does not have a "draw the tile only once" option. Clamp_TileMode | 51 // Skia does not have a "draw the tile only once" option. Clamp_TileMode |
| 51 // repeats the last line of the image after drawing one tile. To avoid | 52 // repeats the last line of the image after drawing one tile. To avoid |
| 52 // filling the space with arbitrary pixels, this workaround forces the | 53 // filling the space with arbitrary pixels, this workaround forces the |
| 53 // image to have a line of transparent pixels on the "repeated" edge(s), | 54 // image to have a line of transparent pixels on the "repeated" edge(s), |
| 54 // thus causing extra space to be transparent filled. | 55 // thus causing extra space to be transparent filled. |
| 55 SkShader::TileMode tileModeX = | 56 SkShader::TileMode tileModeX = |
| 56 isRepeatX() ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode; | 57 isRepeatX() ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode; |
| 57 SkShader::TileMode tileModeY = | 58 SkShader::TileMode tileModeY = |
| 58 isRepeatY() ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode; | 59 isRepeatY() ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode; |
| 59 int borderPixelX = isRepeatX() ? 0 : 1; | 60 int borderPixelX = isRepeatX() ? 0 : 1; |
| 60 int borderPixelY = isRepeatY() ? 0 : 1; | 61 int borderPixelY = isRepeatY() ? 0 : 1; |
| 61 | 62 |
| 62 // Create a transparent image 2 pixels wider and/or taller than the | 63 // Create a transparent image 2 pixels wider and/or taller than the |
| 63 // original, then copy the orignal into the middle of it. | 64 // original, then copy the orignal into the middle of it. |
| 64 // FIXME: Is there a better way to pad (not scale) an image in skia? | 65 // FIXME: Is there a better way to pad (not scale) an image in skia? |
| 65 sk_sp<SkSurface> surface = | 66 sk_sp<SkSurface> surface = |
| 66 SkSurface::MakeRasterN32Premul(m_tileImage->width() + 2 * borderPixelX, | 67 SkSurface::MakeRasterN32Premul(m_tileImage->width() + 2 * borderPixelX, |
| 67 m_tileImage->height() + 2 * borderPixelY); | 68 m_tileImage->height() + 2 * borderPixelY); |
| 68 if (!surface) | 69 if (!surface) |
| 69 return SkShader::MakeColorShader(SK_ColorTRANSPARENT); | 70 return WrapSkShader(SkShader::MakeColorShader(SK_ColorTRANSPARENT)); |
| 70 | 71 |
| 71 SkPaint paint; | 72 SkPaint paint; |
| 72 paint.setBlendMode(SkBlendMode::kSrc); | 73 paint.setBlendMode(SkBlendMode::kSrc); |
| 73 surface->getCanvas()->drawImage(m_tileImage, borderPixelX, borderPixelY, | 74 surface->getCanvas()->drawImage(m_tileImage, borderPixelX, borderPixelY, |
| 74 &paint); | 75 &paint); |
| 75 | 76 |
| 76 m_previousLocalMatrix = localMatrix; | 77 m_previousLocalMatrix = localMatrix; |
| 77 SkMatrix adjustedMatrix(localMatrix); | 78 SkMatrix adjustedMatrix(localMatrix); |
| 78 adjustedMatrix.postTranslate(-borderPixelX, -borderPixelY); | 79 adjustedMatrix.postTranslate(-borderPixelX, -borderPixelY); |
| 79 | 80 |
| 80 return surface->makeImageSnapshot()->makeShader(tileModeX, tileModeY, | 81 return MakeCdlImageShader(surface->makeImageSnapshot(), tileModeX, tileModeY, |
| 81 &adjustedMatrix); | 82 &adjustedMatrix); |
| 82 } | 83 } |
| 83 | 84 |
| 84 bool ImagePattern::isTextureBacked() const { | 85 bool ImagePattern::isTextureBacked() const { |
| 85 return m_tileImage && m_tileImage->isTextureBacked(); | 86 return m_tileImage && m_tileImage->isTextureBacked(); |
| 86 } | 87 } |
| 87 | 88 |
| 88 } // namespace blink | 89 } // namespace blink |
| OLD | NEW |