1635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project/* 2635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright (C) 2008 Google Inc. All rights reserved. 3635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 4635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Redistribution and use in source and binary forms, with or without 5635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * modification, are permitted provided that the following conditions 6635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * are met: 7635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 8635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 9635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * notice, this list of conditions and the following disclaimer. 10635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 11635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 12635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * documentation and/or other materials provided with the distribution. 13635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * its contributors may be used to endorse or promote products derived 15635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * from this software without specific prior written permission. 16635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 17635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project */ 28635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 29635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "config.h" 30635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Pattern.h" 31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 328a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#include "AffineTransform.h" 33635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Image.h" 34635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "NativeImageSkia.h" 35635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 36635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "SkCanvas.h" 370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "SkColor.h" 380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "SkColorShader.h" 390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "SkShader.h" 40635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 41635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectnamespace WebCore { 42635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 435e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blockvoid Pattern::platformDestroy() 44635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 45bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen SkSafeUnref(m_pattern); 465e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block m_pattern = 0; 475e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 485e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 498a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve BlockPlatformPatternPtr Pattern::platformPattern(const AffineTransform& patternTransform) 505e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 515e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block if (m_pattern) 525e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return m_pattern; 535e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 54635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Note: patternTransform is ignored since it seems to be applied elsewhere 55635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // (when the pattern is used?). Applying it to the pattern (i.e. 56635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // shader->setLocalMatrix) results in a double transformation. This can be 57635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // seen, for instance, as an extra offset in: 58635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // LayoutTests/fast/canvas/patternfill-repeat.html 59635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // and expanded scale and skew in: 60635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // LayoutTests/svg/W3C-SVG-1.1/pservers-grad-06-b.svg 61635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 62635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project SkBitmap* bm = m_tileImage->nativeImageForCurrentFrame(); 630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // If we don't have a bitmap, return a transparent shader. 640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (!bm) 655e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block m_pattern = new SkColorShader(SkColorSetARGB(0, 0, 0, 0)); 660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 675e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block else if (m_repeatX && m_repeatY) 685e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block m_pattern = SkShader::CreateBitmapShader(*bm, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); 69635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 705e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block else { 71635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 725e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // Skia does not have a "draw the tile only once" option. Clamp_TileMode 735e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // repeats the last line of the image after drawing one tile. To avoid 745e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // filling the space with arbitrary pixels, this workaround forces the 755e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // image to have a line of transparent pixels on the "repeated" edge(s), 765e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // thus causing extra space to be transparent filled. 775e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block SkShader::TileMode tileModeX = m_repeatX ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode; 785e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block SkShader::TileMode tileModeY = m_repeatY ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode; 795e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block int expandW = m_repeatX ? 0 : 1; 805e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block int expandH = m_repeatY ? 0 : 1; 815e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 825e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // Create a transparent bitmap 1 pixel wider and/or taller than the 835e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // original, then copy the orignal into it. 845e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block // FIXME: Is there a better way to pad (not scale) an image in skia? 855e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block SkBitmap bm2; 865e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block bm2.setConfig(bm->config(), bm->width() + expandW, bm->height() + expandH); 875e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block bm2.allocPixels(); 885e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block bm2.eraseARGB(0x00, 0x00, 0x00, 0x00); 895e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block SkCanvas canvas(bm2); 905e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block canvas.drawBitmap(*bm, 0, 0); 915e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block m_pattern = SkShader::CreateBitmapShader(bm2, tileModeX, tileModeY); 925e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block } 935e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block m_pattern->setLocalMatrix(m_patternSpaceTransformation); 945e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return m_pattern; 955e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 965e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 975e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blockvoid Pattern::setPlatformPatternSpaceTransform() 985e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 995e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block if (m_pattern) 1005e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block m_pattern->setLocalMatrix(m_patternSpaceTransformation); 101635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 102635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 103635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} // namespace WebCore 104