Chromium Code Reviews| Index: Source/platform/graphics/Pattern.cpp |
| diff --git a/Source/platform/graphics/Pattern.cpp b/Source/platform/graphics/Pattern.cpp |
| index 2c889683b038ce3e5e2d9ac6f21ea33ded08d250..ecd379ee9813776f7d0498dd56d463157c128c24 100644 |
| --- a/Source/platform/graphics/Pattern.cpp |
| +++ b/Source/platform/graphics/Pattern.cpp |
| @@ -24,86 +24,107 @@ |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| - |
| #include "config.h" |
| #include "platform/graphics/Pattern.h" |
| -#include <v8.h> |
| -#include "SkCanvas.h" |
| -#include "SkColorShader.h" |
| +#include "platform/graphics/BitmapPattern.h" |
| +#include "platform/graphics/StaticBitmapPattern.h" |
| #include "platform/graphics/skia/SkiaUtils.h" |
| - |
| +#include "third_party/skia/include/core/SkCanvas.h" |
| +#include "third_party/skia/include/core/SkImage.h" |
| +#include <v8.h> |
| namespace blink { |
| -Pattern::Pattern(PassRefPtr<Image> image, bool repeatX, bool repeatY) |
| - : m_repeatX(repeatX) |
| - , m_repeatY(repeatY) |
| - , m_externalMemoryAllocated(0) |
| +PassRefPtr<Pattern> Pattern::create(PassRefPtr<Image> tileImage, bool repeatX, bool repeatY) |
| { |
| - if (image) { |
| - m_tileImage = image->nativeImageForCurrentFrame(); |
| - } |
| + if (tileImage->image()) |
| + return StaticBitmapPattern::create(tileImage, repeatX, repeatY); |
| + |
| + return BitmapPattern::create(tileImage, repeatX, repeatY); |
| } |
| Pattern::~Pattern() |
| { |
| - if (m_externalMemoryAllocated) |
| - v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_externalMemoryAllocated); |
| + adjustExternalMemoryAllocated(-m_externalMemoryAllocated); |
| } |
| -SkShader* Pattern::shader() |
| +void Pattern::setPatternSpaceTransform(const AffineTransform& patternSpaceTransformation) |
| { |
| + m_patternSpaceTransformation = patternSpaceTransformation; |
| if (m_pattern) |
| - return m_pattern.get(); |
| - |
| - SkMatrix localMatrix = affineTransformToSkMatrix(m_patternSpaceTransformation); |
| + m_pattern.clear(); |
| +} |
| - // If we don't have a bitmap, return a transparent shader. |
| - if (!m_tileImage) |
| - m_pattern = adoptRef(new SkColorShader(SK_ColorTRANSPARENT)); |
| - else if (m_repeatX && m_repeatY) |
| - m_pattern = adoptRef(SkShader::CreateBitmapShader(m_tileImage->bitmap(), SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &localMatrix)); |
| - else { |
| - // Skia does not have a "draw the tile only once" option. Clamp_TileMode |
| - // repeats the last line of the image after drawing one tile. To avoid |
| - // filling the space with arbitrary pixels, this workaround forces the |
| - // image to have a line of transparent pixels on the "repeated" edge(s), |
| - // thus causing extra space to be transparent filled. |
| - SkShader::TileMode tileModeX = m_repeatX ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode; |
| - SkShader::TileMode tileModeY = m_repeatY ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode; |
| - int expandW = m_repeatX ? 0 : 1; |
| - int expandH = m_repeatY ? 0 : 1; |
| - |
| - // Create a transparent bitmap 1 pixel wider and/or taller than the |
| - // original, then copy the orignal into it. |
| - // FIXME: Is there a better way to pad (not scale) an image in skia? |
| - SkImageInfo info = m_tileImage->bitmap().info(); |
| - info.fWidth += expandW; |
| - info.fHeight += expandH; |
| - // we explicitly require non-opaquness, since we are going to add a transparent strip. |
| - info.fAlphaType = kPremul_SkAlphaType; |
| - |
| - SkBitmap bm2; |
| - bm2.allocPixels(info); |
| - bm2.eraseARGB(0x00, 0x00, 0x00, 0x00); |
| - SkCanvas canvas(bm2); |
| - canvas.drawBitmap(m_tileImage->bitmap(), 0, 0); |
| - bm2.setImmutable(); |
| - m_pattern = adoptRef(SkShader::CreateBitmapShader(bm2, tileModeX, tileModeY, &localMatrix)); |
| - |
| - // Clamp to int, since that's what the adjust function takes. |
| - m_externalMemoryAllocated = static_cast<int>(std::min(static_cast<size_t>(INT_MAX), bm2.getSafeSize())); |
| - v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(m_externalMemoryAllocated); |
| +SkShader* Pattern::shader(SkShader::ShaderLocation preferredLocation) |
| +{ |
| + if (!m_pattern) { |
| + m_pattern = createShader(preferredLocation); |
| } |
| + |
| return m_pattern.get(); |
| } |
| -void Pattern::setPatternSpaceTransform(const AffineTransform& patternSpaceTransformation) |
| +void Pattern::adjustExternalMemoryAllocated(int64_t delta) |
| { |
| - m_patternSpaceTransformation = patternSpaceTransformation; |
| - if (m_pattern) |
| - m_pattern.clear(); |
| + delta = std::max(-m_externalMemoryAllocated, delta); |
| + |
| + v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(delta); |
| + |
| + m_externalMemoryAllocated += delta; |
| +} |
| + |
| +BitmapBackedPattern::BitmapBackedPattern(bool repeatX, bool repeatY, int64_t externalMemoryAllocated) : Pattern(repeatX, repeatY, externalMemoryAllocated) { } |
| + |
| +BitmapBackedPattern::~BitmapBackedPattern() { } |
| + |
| +PassRefPtr<SkShader> BitmapBackedPattern::createShader(SkShader::ShaderLocation preferredLocation) |
|
Justin Novosad
2014/08/05 17:31:26
unused argument should be commented-out
Rémi Piotaix
2014/08/06 18:09:14
Done.
|
| +{ |
| + // Skia does not have a "draw the tile only once" option. Clamp_TileMode |
| + // repeats the last line of the image after drawing one tile. To avoid |
| + // filling the space with arbitrary pixels, this workaround forces the |
| + // image to have a line of transparent pixels on the "repeated" edge(s), |
| + // thus causing extra space to be transparent filled. |
| + SkShader::TileMode tileModeX = m_repeatX ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode; |
| + SkShader::TileMode tileModeY = m_repeatY ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode; |
| + int expandW = m_repeatX ? 0 : 1; |
| + int expandH = m_repeatY ? 0 : 1; |
| + |
| + // Create a transparent bitmap 1 pixel wider and/or taller than the |
| + // original, then copy the orignal into it. |
| + // FIXME: Is there a better way to pad (not scale) an image in skia? |
| + SkImageInfo info = this->getBitmapInfo(); |
| + info.fWidth = info.width() + expandW; |
| + info.fHeight = info.height() + expandH; |
| + // we explicitly require non-opaquness, since we are going to add a transparent strip. |
| + info.fAlphaType = kPremul_SkAlphaType; |
| + |
| + SkBitmap bm2; |
| + bm2.allocPixels(info); |
| + SkCanvas canvas(bm2); |
| + |
| + SkPaint paint; |
| + paint.setXfermode(SkXfermode::Create(SkXfermode::kSrc_Mode))->unref(); |
|
Justin Novosad
2014/08/05 17:31:26
You should use the version of setXfermode that tak
Rémi Piotaix
2014/08/06 18:09:14
Done.
|
| + |
| + this->drawBitmapToCanvas(canvas, paint); |
| + |
| + paint.setARGB(0x00, 0x00, 0x00, 0x00); |
| + paint.setStyle(SkPaint::kFill_Style); |
| + |
| + if (!m_repeatX) |
| + canvas.drawRect(SkRect::MakeXYWH(info.width() - 1, 0, 1, info.height()), paint); |
| + |
| + if (!m_repeatY) |
| + canvas.drawRect(SkRect::MakeXYWH(0, info.height()-1, info.width(), 1), paint); |
| + |
| + bm2.setImmutable(); |
| + |
| + // Clamp to int, since that's what the adjust function takes. |
| + adjustExternalMemoryAllocated(bm2.getSafeSize()); |
| + |
| + SkMatrix localMatrix = affineTransformToSkMatrix(m_patternSpaceTransformation); |
| + |
| + return adoptRef(SkShader::CreateBitmapShader(bm2, tileModeX, tileModeY, &localMatrix)); |
| } |
| } |