Home | History | Annotate | Download | only in skia
      1 /*
      2  * Copyright (C) 2008 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     14  *     its contributors may be used to endorse or promote products derived
     15  *     from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include "config.h"
     30 #include "Pattern.h"
     31 
     32 #include "AffineTransform.h"
     33 #include "Image.h"
     34 #include "NativeImageSkia.h"
     35 
     36 #include "SkCanvas.h"
     37 #include "SkColor.h"
     38 #include "SkColorShader.h"
     39 #include "SkShader.h"
     40 
     41 namespace WebCore {
     42 
     43 void Pattern::platformDestroy()
     44 {
     45     m_pattern->safeUnref();
     46     m_pattern = 0;
     47 }
     48 
     49 PlatformPatternPtr Pattern::platformPattern(const AffineTransform& patternTransform)
     50 {
     51     if (m_pattern)
     52         return m_pattern;
     53 
     54     // Note: patternTransform is ignored since it seems to be applied elsewhere
     55     // (when the pattern is used?). Applying it to the pattern (i.e.
     56     // shader->setLocalMatrix) results in a double transformation. This can be
     57     // seen, for instance, as an extra offset in:
     58     // LayoutTests/fast/canvas/patternfill-repeat.html
     59     // and expanded scale and skew in:
     60     // LayoutTests/svg/W3C-SVG-1.1/pservers-grad-06-b.svg
     61 
     62     SkBitmap* bm = m_tileImage->nativeImageForCurrentFrame();
     63     // If we don't have a bitmap, return a transparent shader.
     64     if (!bm)
     65         m_pattern = new SkColorShader(SkColorSetARGB(0, 0, 0, 0));
     66 
     67     else if (m_repeatX && m_repeatY)
     68         m_pattern = SkShader::CreateBitmapShader(*bm, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);
     69 
     70     else {
     71 
     72         // Skia does not have a "draw the tile only once" option. Clamp_TileMode
     73         // repeats the last line of the image after drawing one tile. To avoid
     74         // filling the space with arbitrary pixels, this workaround forces the
     75         // image to have a line of transparent pixels on the "repeated" edge(s),
     76         // thus causing extra space to be transparent filled.
     77         SkShader::TileMode tileModeX = m_repeatX ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode;
     78         SkShader::TileMode tileModeY = m_repeatY ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode;
     79         int expandW = m_repeatX ? 0 : 1;
     80         int expandH = m_repeatY ? 0 : 1;
     81 
     82         // Create a transparent bitmap 1 pixel wider and/or taller than the
     83         // original, then copy the orignal into it.
     84         // FIXME: Is there a better way to pad (not scale) an image in skia?
     85         SkBitmap bm2;
     86         bm2.setConfig(bm->config(), bm->width() + expandW, bm->height() + expandH);
     87         bm2.allocPixels();
     88         bm2.eraseARGB(0x00, 0x00, 0x00, 0x00);
     89         SkCanvas canvas(bm2);
     90         canvas.drawBitmap(*bm, 0, 0);
     91         m_pattern = SkShader::CreateBitmapShader(bm2, tileModeX, tileModeY);
     92     }
     93     m_pattern->setLocalMatrix(m_patternSpaceTransformation);
     94     return m_pattern;
     95 }
     96 
     97 void Pattern::setPlatformPatternSpaceTransform()
     98 {
     99     if (m_pattern)
    100         m_pattern->setLocalMatrix(m_patternSpaceTransformation);
    101 }
    102 
    103 } // namespace WebCore
    104