• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006, 2007, 2008 Apple Computer, Inc.  All rights reserved.
3  * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
4  * Copyright (C) 2013 Google, Inc. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "config.h"
29 #include "platform/graphics/Pattern.h"
30 
31 #include <v8.h>
32 #include "SkCanvas.h"
33 #include "SkColorShader.h"
34 #include "platform/graphics/skia/SkiaUtils.h"
35 
36 
37 namespace WebCore {
38 
Pattern(PassRefPtr<Image> image,bool repeatX,bool repeatY)39 Pattern::Pattern(PassRefPtr<Image> image, bool repeatX, bool repeatY)
40     : m_repeatX(repeatX)
41     , m_repeatY(repeatY)
42     , m_externalMemoryAllocated(0)
43 {
44     if (image) {
45         m_tileImage = image->nativeImageForCurrentFrame();
46     }
47 }
48 
~Pattern()49 Pattern::~Pattern()
50 {
51     if (m_externalMemoryAllocated)
52         v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_externalMemoryAllocated);
53 }
54 
shader()55 SkShader* Pattern::shader()
56 {
57     if (m_pattern)
58         return m_pattern.get();
59 
60     SkMatrix localMatrix = affineTransformToSkMatrix(m_patternSpaceTransformation);
61 
62     // If we don't have a bitmap, return a transparent shader.
63     if (!m_tileImage)
64         m_pattern = adoptRef(new SkColorShader(SK_ColorTRANSPARENT));
65     else if (m_repeatX && m_repeatY)
66         m_pattern = adoptRef(SkShader::CreateBitmapShader(m_tileImage->bitmap(), SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode, &localMatrix));
67     else {
68         // Skia does not have a "draw the tile only once" option. Clamp_TileMode
69         // repeats the last line of the image after drawing one tile. To avoid
70         // filling the space with arbitrary pixels, this workaround forces the
71         // image to have a line of transparent pixels on the "repeated" edge(s),
72         // thus causing extra space to be transparent filled.
73         SkShader::TileMode tileModeX = m_repeatX ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode;
74         SkShader::TileMode tileModeY = m_repeatY ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode;
75         int expandW = m_repeatX ? 0 : 1;
76         int expandH = m_repeatY ? 0 : 1;
77 
78         // Create a transparent bitmap 1 pixel wider and/or taller than the
79         // original, then copy the orignal into it.
80         // FIXME: Is there a better way to pad (not scale) an image in skia?
81         SkImageInfo info = m_tileImage->bitmap().info();
82         info.fWidth += expandW;
83         info.fHeight += expandH;
84         // we explicitly require non-opaquness, since we are going to add a transparent strip.
85         info.fAlphaType = kPremul_SkAlphaType;
86 
87         SkBitmap bm2;
88         bm2.allocPixels(info);
89         bm2.eraseARGB(0x00, 0x00, 0x00, 0x00);
90         SkCanvas canvas(bm2);
91         canvas.drawBitmap(m_tileImage->bitmap(), 0, 0);
92         bm2.setImmutable();
93         m_pattern = adoptRef(SkShader::CreateBitmapShader(bm2, tileModeX, tileModeY, &localMatrix));
94 
95         // Clamp to int, since that's what the adjust function takes.
96         m_externalMemoryAllocated = static_cast<int>(std::min(static_cast<size_t>(INT_MAX), bm2.getSafeSize()));
97         v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(m_externalMemoryAllocated);
98     }
99     return m_pattern.get();
100 }
101 
setPatternSpaceTransform(const AffineTransform & patternSpaceTransformation)102 void Pattern::setPatternSpaceTransform(const AffineTransform& patternSpaceTransformation)
103 {
104     m_patternSpaceTransformation = patternSpaceTransformation;
105     if (m_pattern)
106         m_pattern.clear();
107 }
108 
109 }
110